[swift-evolution] [Proposal draft] Introducing `indexed()` collections
Dave Abrahams
dabrahams at apple.com
Tue Oct 4 15:47:05 CDT 2016
on Mon Oct 03 2016, Kevin Ballard <swift-evolution at swift.org> wrote:
> On Mon, Oct 3, 2016, at 02:51 PM, Dave Abrahams via swift-evolution wrote:
>>
>> on Mon Oct 03 2016, Kevin Ballard <swift-evolution at swift.org> wrote:
>>
>> > On Fri, Sep 30, 2016, at 08:53 PM, Dave Abrahams via swift-evolution wrote:
>> >>
>
>> >> on Wed Sep 28 2016, Erica Sadun <swift-evolution at swift.org> wrote:
>> >>
>> >> > Indices have a specific, fixed meaning in Swift, which are used to create valid collection
>> >> > subscripts. This proposal introduces indexed() to produce a more semantically relevant sequence
>> > by
>> >
>> >> > pairing a collection's indices with its members. While it is trivial to create a solution in Swift,
>> >> > the most common developer approach shown here calculates indexes twice:
>> >> >
>> >> > extension Collection {
>> >> > /// Returns a sequence of pairs (*idx*, *x*), where *idx* represents a
>> >> > /// consecutive collection index, and *x* represents an element of
>> >> > /// the sequence.
>> >> > func indexed() -> Zip2Sequence<Self.Indices, Self> {
>> >> > return zip(indices, self)
>> >> > }
>> >> > }
>> >>
>> >> How does this calculate indices twice?
>> >
>> > It calculates indices twice for any collection that uses
>> > IndexingIterator as its iterator.
>>
>> Yes. Not in general; just in that particular case.
>>
>> > And for collections that doesn't, it still does the moral equivalent,
>> > because it's calculating an index offset along with whatever work the
>> > Iterator does to calculate the next element.
>>
>> Indexing is supposed to be cheap; almost free. Lazy filtered
>> collections are an anomaly. They're arguably not even legal
>> Collections, because advancing an index may not be O(1). They exist
>> because they're useful, but you shouldn't pass them out without
>> understanding the consequences.
>
> Using an index is supposed to be cheap/free. Calculating the next
> index is not guaranteed to be so.
It's supposed to be so.
> If you want another example of something that's not lazy, try
> String.CharacterView. Calculating the next index may be arbitrarily
> complex since I can string as many combining marks together as I want,
> though in practice it will be pretty cheap. But even this "pretty
> cheap" is still work, and depending on what I'm doing in the loop,
> calculating character indexes may be a significant fraction of the
> work performed.
Okay, you do have a point, here. Also, Dictionary and Set can have
similar cost profiles for advancing an index.
>> > As an example, if my collection is `someArray.lazy.filter(…)` then
>> > zip(col.indices, col) will run the filter twice over the collection.
>>
>> Okay.
>>
>> >> > Incrementing an index in some collections can be unnecessarily
>> >> > costly.
>> >>
>> >> Seems like it's only *unnecessarily* costly in badly implemented
>> >> collections?
>> >
>> > A collection doesn't have to be badly-implemented to have a
>> > non-trivial cost for calculating the next element.
To be clear, in those cases it is a necessary cost.
>> > As above, someArray.lazy.filter(…) is a good example of such a
>> > collection.
>>
>> Its conformance to Collection is quite sketchy.
>
> But it's not the only collection where calculating indexes is
> non-trivial.
Okay. Well, I suggest we bring this up again in phase 2, when it's
actionable.
--
-Dave
More information about the swift-evolution
mailing list