<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 28 Sep 2016, at 23:44, Kevin Ballard <<a href="mailto:kevin@sb.org" class="">kevin@sb.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">
<title class=""></title>
<div class=""><div class="">On Wed, Sep 28, 2016, at 02:10 PM, Tim Vermeulen wrote:<br class=""></div>
<blockquote type="cite" class=""><div class=""><br class=""></div>
<div class=""><blockquote type="cite" class=""><div class="">On 28 Sep 2016, at 23:03, Kevin Ballard <<a href="mailto:kevin@sb.org" class="">kevin@sb.org</a>> wrote:<br class=""></div>
<div class=""><br class=""></div>
<div class=""><div class=""><div class="">On Wed, Sep 28, 2016, at 02:02 PM, Tim Vermeulen wrote:<br class=""></div>
<blockquote type="cite" class=""><div class=""><br class=""></div>
<blockquote type="cite" class=""><div class="">On 28 Sep 2016, at 22:57, Kevin Ballard <<a href="mailto:kevin@sb.org" class="">kevin@sb.org</a>> wrote:<br class=""></div>
<div class=""><br class=""></div>
<div class="">On Wed, Sep 28, 2016, at 01:54 PM, Tim Vermeulen wrote:<br class=""></div>
<blockquote type="cite" class=""><div class=""><br class=""></div>
<blockquote type="cite" class=""><div class="">On 28 Sep 2016, at 22:46, Kevin Ballard <<a href="mailto:kevin@sb.org" class="">kevin@sb.org</a>> wrote:<br class=""></div>
<div class=""><br class=""></div>
<div class="">That's a bunch of complexity for no benefit. Why would you ever use this as a collection?<br class=""></div>
</blockquote><div class=""><br class=""></div>
<div class="">I think there is a benefit. Something like `collection.indexed().reversed()` would benefit from that, and I think that could be useful.<br class=""></div>
</blockquote><div class=""><br class=""></div>
<div class="">Perhaps, though you could just say `collection.reversed().indexed()` instead.<br class=""></div>
</blockquote><div class=""><br class=""></div>
<div class="">This isn’t necessarily the same though, is it? The reversed collection might use different indices than the original collection.<br class=""></div>
</blockquote><div class=""><br class=""></div>
<div class="">Either way you write it you're dealing with reversed indices.<br class=""></div>
</div>
</div>
</blockquote><div class=""><br class=""></div>
<div class="">`collection.indexed().reversed()` will contain indices from the original collection (but in reversed order). `collection.reversed().indexed()` will contain indices from the collection returned by `reversed()`, which may have a different type than `Base.Index`. It’s a distinction.<br class=""></div>
<div class=""><br class=""></div>
<div class="">This would compile:<br class=""></div>
<div class=""><br class=""></div>
<div class=""><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;" class=""><span class="colour" style="color:rgb(186, 45, 162)">let</span><span style="font-variant-ligatures:no-common-ligatures;" class=""> characters = </span><span class="colour" style="color:rgb(209, 47, 27)">"Swift"</span><span style="font-variant-ligatures:no-common-ligatures;" class="">.</span><span class="colour" style="color:rgb(112, 61, 170)">characters</span><br class=""></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px;" class=""><span style="font-variant-ligatures:no-common-ligatures;" class=""></span><br class=""></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;" class=""><span class="colour" style="color:rgb(186, 45, 162)">for</span><span style="font-variant-ligatures:no-common-ligatures;" class=""> (index, character) </span><span class="colour" style="color:rgb(186, 45, 162)">in</span><span style="font-variant-ligatures:no-common-ligatures;" class=""> </span><span class="colour" style="color:rgb(79, 129, 135)">characters</span><span style="font-variant-ligatures:no-common-ligatures;" class="">.</span><span class="colour" style="color:rgb(49, 89, 93)">indexed</span><span style="font-variant-ligatures:no-common-ligatures;" class="">().</span><span class="colour" style="color:rgb(62, 30, 129)">reversed</span><span style="font-variant-ligatures:no-common-ligatures;" class="">() {</span><br class=""></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;" class=""><span style="font-variant-ligatures:no-common-ligatures;" class=""> </span><span class="colour" style="color:rgb(62, 30, 129)">print</span><span style="font-variant-ligatures:no-common-ligatures;" class="">(</span><span class="colour" style="color:rgb(79, 129, 135)">characters</span><span style="font-variant-ligatures:no-common-ligatures;" class="">[index], character)</span><br class=""></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;" class=""><span style="font-variant-ligatures:no-common-ligatures;" class="">}</span><br class=""></div>
</div>
<div class=""><br class=""></div>
<div class="">This wouldn’t:<br class=""></div>
<div class=""><br class=""></div>
<div class=""><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;" class=""><span class="colour" style="color:rgb(186, 45, 162)">let</span><span style="font-variant-ligatures:no-common-ligatures;" class=""> characters = </span><span class="colour" style="color:rgb(209, 47, 27)">"Swift"</span><span style="font-variant-ligatures:no-common-ligatures;" class="">.</span><span class="colour" style="color:rgb(112, 61, 170)">characters</span><br class=""></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px;" class=""><span style="font-variant-ligatures:no-common-ligatures;" class=""></span><br class=""></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;" class=""><span class="colour" style="color:rgb(186, 45, 162)">for</span><span style="font-variant-ligatures:no-common-ligatures;" class=""> (index, character) </span><span class="colour" style="color:rgb(186, 45, 162)">in</span><span style="font-variant-ligatures:no-common-ligatures;" class=""> </span><span class="colour" style="color:rgb(79, 129, 135)">characters</span><span style="font-variant-ligatures:no-common-ligatures;" class="">.</span><span class="colour" style="color:rgb(62, 30, 129)">reversed</span><span style="font-variant-ligatures:no-common-ligatures;" class="">().</span><span class="colour" style="color:rgb(49, 89, 93)">indexed</span><span style="font-variant-ligatures:no-common-ligatures;" class="">() {</span><br class=""></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;" class=""><span style="font-variant-ligatures:no-common-ligatures;" class=""> print(</span><span class="colour" style="color:rgb(79, 129, 135)">characters</span><span style="font-variant-ligatures:no-common-ligatures;" class="">[index], character)</span><br class=""></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font-size:11px;line-height:normal;font-family:Menlo;" class=""><span style="font-variant-ligatures:no-common-ligatures;" class="">}</span><br class=""></div>
</div>
</div>
</blockquote><div class=""><br class=""></div>
<div class="">Oh you're right.<br class=""></div>
<div class=""><br class=""></div>
<div class="">Still, it's a fair amount of complexity (handling bidirectional and random-access collections on top of the regular collection) and I'm not sure it's worth the complexity just for reversed().</div></div></div></blockquote><div><br class=""></div><div>It’s very straight-forward to simply forward all requirements to the base collection. I just wrote it out, and it might even be less complex than the sequence approach, because we don’t need a custom iterator.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><div class="">After all, you can always fall back to the slightly uglier<br class=""></div>
<div class=""><br class=""></div>
<div class="">for index in characters.indices.reversed() {<br class=""></div>
<div class=""> let character = characters[index]<br class=""></div>
<div class=""> ...<br class=""></div>
<div class="">}<br class=""></div></div></div></blockquote><div><br class=""></div><div>You could, but don’t forget that writing `characters.indexed().reversed()` in the case of `IndexedSequence` would still have the result you’d expect. It’s simply less efficient than necessary. Most people probably wouldn’t even realise that the more readable approach isn’t the most efficient one, here.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="">
<div class=""><br class=""></div>
<div class="">And it's worth pointing out that enumerated() doesn't return a collection but nobody's been clamoring for reversed() support there.<br class=""></div>
<div class=""><br class=""></div>
<div class="">-Kevin</div>
<div class=""><br class=""></div>
<blockquote type="cite" class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""><div class=""><br class=""></div>
<div class="">-Kevin<br class=""></div>
<div class=""><br class=""></div>
<blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">The whole point is to be used in a for loop. If it was a collection then you'd need to have an index for that collection, so now you have an index that lets you get the index for another collection, which is pretty useless because you could just be using that underlying index to begin with.<br class=""></blockquote><div class=""><br class=""></div>
<div class="">Rather than introducing a new index for this, we can simply use the index of the base collection for subscripting.<br class=""></div>
</blockquote><div class=""><br class=""></div>
<div class="">That's actually a good idea, and if we do make it a collection this is probably how we should handle it. But I still argue that the ability to make something a collection doesn't mean it should be a collection, if there's no good reason for anyone to actually try to use it as such.<br class=""></div>
<div class=""><br class=""></div>
<div class="">-Kevin<br class=""></div>
<div class=""><br class=""></div>
<blockquote type="cite" class=""><blockquote type="cite" class=""><div class="">On Wed, Sep 28, 2016, at 01:38 PM, Tim Vermeulen via swift-evolution wrote:<br class=""></div>
<blockquote type="cite" class=""><div class="">+1 for `indexed()`, but I’m not sure about `IndexedSequence`. Why not `IndexedCollection`, which could also conform to Collection? With conditional conformances to BidirectionalCollection and RandomAccessCollection. This wouldn’t penalise the performance with respect to a simple `IndexedSequence`, would it?<br class=""></div>
<div class=""><br class=""></div>
<blockquote type="cite" class=""><div class="">Gist here:<a href="https://gist.github.com/erica/2b2d92e6db787d001c689d3e37a7c3f2" class="">https://gist.github.com/erica/2b2d92e6db787d001c689d3e37a7c3f2</a><br class=""></div>
<div class=""><br class=""></div>
<div class="">Introducingindexed()collections<br class=""></div>
<div class="">Proposal: TBD<br class=""></div>
<div class="">Author:Erica Sadun(<a href="https://github.com/erica" class="">https://github.com/erica</a>),Nate Cook(<a href="https://github.com/natecook1000" class="">https://github.com/natecook1000</a>),Jacob Bandes-Storch(<a href="https://github.com/jtbandes" class="">https://github.com/jtbandes</a>),Kevin Ballard(<a href="https://github.com/kballard" class="">https://github.com/kballard</a>)<br class=""></div>
<div class="">Status: TBD<br class=""></div>
<div class="">Review manager: TBD<br class=""></div>
<div class=""><br class=""></div>
<div class="">Introduction<br class=""></div>
<div class=""><br class=""></div>
<div class="">This proposal introducesindexed()to the standard library, a method on collections that returns an (index, element) tuple sequence.<br class=""></div>
<div class=""><br class=""></div>
<div class=""><br class=""></div>
<div class="">Swift-evolution thread:TBD(<a href="https://gist.github.com/erica/tbd" class="">https://gist.github.com/erica/tbd</a>)<br class=""></div>
<div class=""><br class=""></div>
<div class="">Motivation<br class=""></div>
<div class=""><br class=""></div>
<div class="">The standard library'senumerated()method returns a sequence of pairs enumerating a sequence. The pair's first member is a monotonically incrementing integer starting at zero, and the second member is the corresponding element of the sequence. When working with arrays, the integer is coincidentally the same type and value as anArrayindex but the enumerated value is not generated with index-specific semantics. This may lead to confusion when developers attempt to subscript a non-array collection with enumerated integers. It can introduce serious bugs when developers useenumerated()-based integer subscripting with non-zero-based array slices.<br class=""></div>
<div class=""><br class=""></div>
<div class=""><br class=""></div>
<div class="">Indices have a specific, fixed meaning in Swift, which are used to create valid collection subscripts. This proposal introducesindexed()to produce a more semantically relevant sequence by pairing a collection'sindiceswith its members. While it is trivial to create a solution in Swift, the most common developer approach shown here calculates indexes twice:<br class=""></div>
<div class=""><br class=""></div>
<div class="">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) } }<br class=""></div>
<div class=""><br class=""></div>
<div class="">Incrementing an index in some collections can be unnecessarily costly. In a lazy filtered collection, an index increment is potentially O(N). We feel this is better addressed introducing a new function into the Standard Library to provide a more efficient design that avoids the attractive nuisance of the "obvious" solution.<br class=""></div>
<div class=""><br class=""></div>
<div class="">Detailed Design<br class=""></div>
<div class=""><br class=""></div>
<div class="">Our vision ofindexed()bypasses duplicated index generation with their potentially high computation costs. We'd create an iterator that calculates each index once and then applies that index to subscript the collection. Implementation would take place throughIndexedSequence, similar toEnumeratedSequence.<br class=""></div>
<div class=""><br class=""></div>
<div class="">Impact on Existing Code<br class=""></div>
<div class=""><br class=""></div>
<div class="">This proposal is purely additive and has no impact on existing code.<br class=""></div>
<div class=""><br class=""></div>
<div class="">Alternatives Considered<br class=""></div>
<div class="">Not yet<br class=""></div>
<div class=""><br class=""></div>
<div class=""><br class=""></div>
<div class=""><br class=""></div>
</blockquote><div class="">_______________________________________________<br class=""></div>
<div class="">swift-evolution mailing list<br class=""></div>
<div class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""></div>
<div class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div>
</blockquote></blockquote></blockquote></blockquote></blockquote></div>
</div>
</blockquote></div>
</blockquote><div class=""><br class=""></div>
</div>
</div></blockquote></div><br class=""></body></html>