I agree that there should be a type for a non-destructive re-entrant sequence.<div><br></div><div>IIRC in past discussions one of the counter arguments given was IO stream sequences. It is likely undesirable to buffer the entire stream, but without buffering there&#39;s no guarantee of getting the same values.</div><div><br></div><div>These discussions were back when swift-evolution started, sorry I couldn&#39;t find a link. I think it was discussed in the context of a non-mutating Generator.<br><br>On Thursday, 23 June 2016, Matthew Johnson via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
&gt; On Jun 22, 2016, at 3:57 PM, Dave Abrahams via swift-evolution &lt;<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;swift-evolution@swift.org&#39;)">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt;<br>
&gt; on Wed Jun 22 2016, David Waite &lt;<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;swift-evolution@swift.org&#39;)">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt;&gt; Today, a Sequence differs from a Collection in that:<br>
&gt;&gt;<br>
&gt;&gt; - A sequence can be infinitely or indefinitely sized, or could require<br>
&gt;&gt; an O(n) operation to count the values in the sequence.<br>
&gt;<br>
&gt; The latter being no different from Collection.<br>
&gt;<br>
&gt;&gt; A collection has a finite number of elements, and the fixed size is<br>
&gt;&gt; exposed as an O(1) or O(n) operation via ‘count’<br>
&gt;<br>
&gt; I don&#39;t believe we&#39;ve actually nailed down that Collection is finite.<br>
&gt;<br>
&gt; Oh, gee, Nate&#39;s documentation edits do<br>
&gt; that. (<a href="https://github.com/apple/swift/commit/6e274913" target="_blank">https://github.com/apple/swift/commit/6e274913</a>)<br>
&gt; Nate, did we discuss this explicitly or did it slip in unnoticed?<br>
&gt;<br>
&gt; The one crucial distinction in Collection is that you can make multiple<br>
&gt; passes over the same elements.<br>
&gt;<br>
&gt;&gt; - A collection is indexable, with those indices being usable for<br>
&gt;&gt; various operations including forming subsets, comparisons, and manual<br>
&gt;&gt; iteration<br>
&gt;&gt;<br>
&gt;&gt; - A sequence may or may not be destructive, where a destructive<br>
&gt;&gt; sequence consumes elements during traversal, making them unavailable<br>
&gt;&gt; on subsequent traversals. Collection operations are required to be<br>
&gt;&gt; non-destructive<br>
&gt;&gt;<br>
&gt;&gt; I would like to Pitch removing this third differentiation, the option<br>
&gt;&gt; for destructive sequences.<br>
&gt;<br>
&gt; I have been strongly considering this direction myself, and it&#39;s<br>
&gt; something we need to decide about for Swift 3.<br>
<br>
I believe this is a problem that should be solved.<br>
<br>
I also believe distinguishing between finite and infinite sequences is a good idea (along with preventing for..in from being used with an infinite sequence)<br>
<br>
&gt;<br>
&gt;&gt; My main motivation for proposing this is the potential for developer<br>
&gt;&gt; confusion. As stated during one of the previous threads on the naming<br>
&gt;&gt; of map, flatMap, filter, etc. methods on Sequence, Sequence has a<br>
&gt;&gt; naming requirement not typical of the rest of the Swift standard<br>
&gt;&gt; library in that many methods on Sequence may or may not be<br>
&gt;&gt; destructive. As such, naming methods for any extensions on Sequence is<br>
&gt;&gt; challenging as the names need to not imply immutability.<br>
&gt;<br>
&gt; I don&#39;t think the names are really the worst potential cause of<br>
&gt; confusion here.  There&#39;s also the fact that you can conform to Sequence<br>
&gt; with a destructively-traversed “value type” that has no mutating<br>
&gt; methods.<br>
<br>
I agree, names are not the primary issue.<br>
<br>
Another issue is that you cannot currently write generic code that might need to iterate a sequence more than once.  You currently have to over-constrain types to `Collection` even if you don’t need to do anything other than iterate the elements (the discussion about whether `LazyFilterSequnce` has a bug in its `underestimateCount` is relevant here).<br>
<br>
&gt;<br>
&gt;&gt; It would still be possible to have Generators which operate<br>
&gt;<br>
&gt; &lt;Ahem&gt; “Iterators,” please.<br>
&gt;<br>
&gt;&gt; destructively, but such Generators would not conform to the needs of<br>
&gt;&gt; Sequence. As such, the most significant impact would be the inability<br>
&gt;&gt; to use such Generators in a for..in loop,<br>
&gt;<br>
&gt; Trying to evaluate this statement, it&#39;s clear we&#39;re missing lots of<br>
&gt; detail here:<br>
&gt;<br>
&gt; * Would you remove Sequence?<br>
&gt; * If so, what Protocol would embody “for...in-able?”<br>
&gt; * If not, would you remove Collection?<br>
&gt; * What role would Iterator play?<br>
<br>
If we’re going to consider alternative designs it is worth considering the semantic space available.  For the sake of discussion, here is a model that captures the various semantics that exist (the names are just strawmen):<br>
<br>
                           Iterable<br>
                           /          \<br>
                          /             \<br>
                         /               \<br>
    FiniteIterable                 MultipassIterable<br>
                        \                 /<br>
                          \              /<br>
                           \            /<br>
                          Sequence<br>
                                 |<br>
                                 |<br>
                          Collection<br>
<br>
`Iterable` corresponds to the current `Sequence` - no semantics beyond iteration are required.  Infinite, single-pass “sequences” may conform.<br>
<br>
`for..in` naturally requires `FiniteIterable`, but does not require the `MultipassIterable`.<br>
<br>
There are many interesting infinite `MultipassIterable` types.  These include any dynamically generated sequence, such as a mathematical sequence (even numbers, odd numbers, etc).  This is also what the existing `Sequence` would become if we drop support for destructive sequences and do nothing else (note: it would still be possible to accidentally write a `for..in` loop over an infinite sequence).<br>
<br>
Under this model `Sequence` brings together `FiniteIterable` and `MultipassIterable`.  This describes the most common models of `Sequence`, can safely be used in a `for..in` loop, and does support “destructive” single pass sequences.<br>
<br>
`FiniteIterable` and `MultipassIterable` introduce independent and important semantic requirements.  If we’re going to consider changes here, I think it is worth at least considering introducing the distinction.<br>
<br>
This is obviously much more complex than than the current design.  The most obvious simplification would be to drop `Iterable` if we don’t have any compelling use cases for infinite, single pass sequences.  One downside to doing this is that the syntactic requirements would need to be repeated in both `FiniteIterable` and `MultipassIterable`<br>
<br>
Another obvious simplification would be to also remove `Sequence` (which becomes a “convenience” protocol under this model) and require types that can conform to both `FiniteIterable` and `MultipassIterable` to do so directly.<br>
<br>
If chose to make both simplifications we could also rename the remaining `FiniteIterable` and `MultipassIterable` to something simpler like `Iterable` and `Sequence`.<br>
<br>
               (for..in)              (the existing `Sequence` with an additional multipass semantic requirement)<br>
               Iterable             Sequence<br>
                        \                 /<br>
                          \              /<br>
                           \            /<br>
                          Collection<br>
<br>
I’m interested in hearing what others think about this way of thinking about the available design space.<br>
<br>
-Matthew<br>
<br>
<br>
&gt;<br>
&gt;<br>
&gt; --<br>
&gt; Dave<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; swift-evolution mailing list<br>
&gt; <a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;swift-evolution@swift.org&#39;)">swift-evolution@swift.org</a><br>
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;swift-evolution@swift.org&#39;)">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>