<div dir="ltr">Jordan Rose has a thought in PermutationGenerator thread that about any GeneratorType "is-a" SequenceType. (I missed the thread)<div><a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/005525.html">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/005525.html</a><br><div><br></div><div>So i get a graph with:</div><div><br></div><div>SequenceType -----------------------------------> CollectionType</div><div> ∟ generate() ----> GeneratorType</div><div><br></div><div>if this correct, we will redefine the GeneratorType as SequenceType</div><div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">/// Encapsulates iteration state and interface for iteration over a</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">/// *sequence*.</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">///</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">/// - Note: While it is safe to copy a *generator*, advancing one</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">/// copy may invalidate the others.</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">///</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">/// Any code that uses multiple generators (or `for`...`in` loops)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">/// over a single *sequence* should have static knowledge that the</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">/// specific *sequence* is multi-pass, either because its concrete</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">/// type is known or because it is constrained to `CollectionType`.</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">/// Also, the generators must be obtained by distinct calls to the</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">/// *sequence's* `generate()` method, rather than by copying.</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">public</span> <span style="color:rgb(187,44,162)">protocol</span> GeneratorType : <span style="color:rgb(112,61,170)">SequenceType</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"> </span>/// The type of element generated by `self`.</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">typealias</span> Element</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"> </span>/// Advance to the next element and return it, or `nil` if no next</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"> </span>/// element exists.</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(0,132,0)">///</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"> </span>/// - Requires: `next()` has not been applied to a copy of `self`</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"> </span>/// since the copy was made, and no preceding call to `self.next()`</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"> </span>/// has returned `nil`. Specific implementations of this protocol</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"> </span>/// are encouraged to respond to violations of this requirement by</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"> </span>/// calling `preconditionFailure("...")`.</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(187,44,162)"><span style="color:rgb(0,0,0)"> </span>@warn_unused_result</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">public</span> <span style="color:rgb(187,44,162)">mutating</span> <span style="color:rgb(187,44,162)">func</span> next() -> <span style="color:rgb(112,61,170)">Self</span>.<span style="color:rgb(112,61,170)">Element</span>?</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(187,44,162)">extension</span><span style="color:rgb(0,0,0)"> </span>GeneratorType<span style="color:rgb(0,0,0)"> {</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">public</span> <span style="color:rgb(187,44,162)">func</span> generate() -> <span style="color:rgb(112,61,170)">Self</span> {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(187,44,162)"><span style="color:rgb(0,0,0)"> </span>return<span style="color:rgb(0,0,0)"> </span>self</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span style="font-family:arial,sans-serif;font-size:small">and discard this(break </span><span style="font-family:arial,sans-serif;font-size:small">circularity between SequenceType and GeneratorType</span><span style="font-family:arial,sans-serif;font-size:small">):</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">extension</span> <span style="color:rgb(112,61,170)">SequenceType</span> <span style="color:rgb(187,44,162)">where</span> <span style="color:rgb(187,44,162)">Self</span>.Generator == <span style="color:rgb(187,44,162)">Self</span>, <span style="color:rgb(187,44,162)">Self</span> : GeneratorType {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">public</span> <span style="color:rgb(187,44,162)">func</span> generate() -> <span style="color:rgb(112,61,170)">Self</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="font-family:arial,sans-serif;font-size:small">also, </span><span style="font-family:arial,sans-serif;font-size:small">adding the follows to stdlib:</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(187,44,162)">public<span style="color:rgb(0,0,0)"> </span>extension<span style="color:rgb(0,0,0)"> </span><span style="color:rgb(112,61,170)">SequenceType</span><span style="color:rgb(0,0,0)"> </span>where<span style="color:rgb(0,0,0)"> </span>Self<span style="color:rgb(0,0,0)"> : Indexable {</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">var</span> startIndex: <span style="color:rgb(79,129,135)">MultipassIndex</span><<span style="color:rgb(112,61,170)">Generator</span>> {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">var</span> g = <span style="color:rgb(187,44,162)">self</span>.<span style="color:rgb(61,29,129)">enumerate</span>().<span style="color:rgb(61,29,129)">generate</span>()</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">if</span> <span style="color:rgb(187,44,162)">let</span> (idx, val) = g.<span style="color:rgb(61,29,129)">next</span>() {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> <span style="color:rgb(79,129,135)">MultipassIndex</span>(reachEnd: <span style="color:rgb(187,44,162)">false</span>, index: idx, buffer: val, generator: g)</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> <span style="color:rgb(79,129,135)">MultipassIndex</span>(reachEnd: <span style="color:rgb(187,44,162)">true</span>, index: <span style="color:rgb(187,44,162)">nil</span>, buffer: <span style="color:rgb(187,44,162)">nil</span>, generator: g)</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">var</span> endIndex: <span style="color:rgb(79,129,135)">MultipassIndex</span><<span style="color:rgb(112,61,170)">Generator</span>> {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> <span style="color:rgb(79,129,135)">MultipassIndex</span>(reachEnd: <span style="color:rgb(187,44,162)">true</span>, index: <span style="color:rgb(187,44,162)">nil</span>, buffer: <span style="color:rgb(187,44,162)">nil</span>, generator: <span style="color:rgb(187,44,162)">self</span>.<span style="color:rgb(61,29,129)">enumerate</span>().<span style="color:rgb(61,29,129)">generate</span>())</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">subscript</span>(position: <span style="color:rgb(79,129,135)">MultipassIndex</span><<span style="color:rgb(112,61,170)">Generator</span>>) -> <span style="color:rgb(112,61,170)">Generator</span>.<span style="color:rgb(112,61,170)">Element</span> {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> position.<span style="color:rgb(79,129,135)">buffer</span>!</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// Note: Requires G has value semantics</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">public</span> <span style="color:rgb(187,44,162)">struct</span> MultipassIndex<G: GeneratorType> : <span style="color:rgb(112,61,170)">ForwardIndexType</span> {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">public</span> <span style="color:rgb(187,44,162)">func</span> successor() -> <span style="color:rgb(79,129,135)">MultipassIndex</span> {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">var</span> r = <span style="color:rgb(187,44,162)">self</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">if</span> !<span style="color:rgb(79,129,135)">reachEnd</span>, <span style="color:rgb(187,44,162)">let</span> (idx, val) = r.<span style="color:rgb(79,129,135)">generator</span>.<span style="color:rgb(61,29,129)">next</span>() {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> r.<span style="color:rgb(79,129,135)">index</span> = idx</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> r.<span style="color:rgb(79,129,135)">buffer</span> = val</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> } <span style="color:rgb(187,44,162)">else</span> {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> r.<span style="color:rgb(79,129,135)">reachEnd</span> = <span style="color:rgb(187,44,162)">true</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> r.<span style="color:rgb(79,129,135)">index</span> = <span style="color:rgb(187,44,162)">nil</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> r.<span style="color:rgb(79,129,135)">buffer</span> = <span style="color:rgb(187,44,162)">nil</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> r</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">var</span> reachEnd: <span style="color:rgb(112,61,170)">Bool</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">var</span> index: <span style="color:rgb(112,61,170)">Int</span>?</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">var</span> buffer: <span style="color:rgb(112,61,170)">G</span>.<span style="color:rgb(112,61,170)">Element</span>?</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(187,44,162)">var</span><span style="color:rgb(0,0,0)"> generator: </span>EnumerateGenerator<span style="color:rgb(0,0,0)"><</span>G<span style="color:rgb(0,0,0)">></span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(79,129,135)"><span style="color:rgb(187,44,162)">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(187,44,162)">func</span><span style="color:rgb(0,0,0)"> == <T>(x: </span>MultipassIndex<span style="color:rgb(0,0,0)"><</span>T<span style="color:rgb(0,0,0)">>, y: </span>MultipassIndex<span style="color:rgb(0,0,0)"><</span>T<span style="color:rgb(0,0,0)">>) -> </span><span style="color:rgb(112,61,170)">Bool</span><span style="color:rgb(0,0,0)"> {</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> x.<span style="color:rgb(79,129,135)">index</span> == y.<span style="color:rgb(79,129,135)">index</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></p><p style="margin:0px;line-height:normal"><span style="font-family:arial,sans-serif;font-size:small">That means we can defined a collection as </span>follows and implement Indexable automatically:</p><p style="margin:0px;line-height:normal"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(187,44,162)">struct</span><span style="color:rgb(0,0,0)"> Fib : </span>CollectionType<span style="color:rgb(0,0,0)"> {</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">typealias</span> Generator = <span style="color:rgb(79,129,135)">FibGenerator</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">var</span> a, b: <span style="color:rgb(112,61,170)">Int</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">func</span> generate() -> <span style="color:rgb(79,129,135)">FibGenerator</span> {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> <span style="color:rgb(79,129,135)">FibGenerator</span>(a: <span style="color:rgb(79,129,135)">a</span>, b: <span style="color:rgb(79,129,135)">b</span>)</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">struct</span> FibGenerator : <span style="color:rgb(112,61,170)">GeneratorType</span> {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">var</span> a, b: <span style="color:rgb(112,61,170)">Int</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">mutating</span> <span style="color:rgb(187,44,162)">func</span> next() -> <span style="color:rgb(112,61,170)">Int</span>? {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">let</span> temp = <span style="color:rgb(79,129,135)">a</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> (<span style="color:rgb(79,129,135)">a</span>, <span style="color:rgb(79,129,135)">b</span>) = (<span style="color:rgb(79,129,135)">b</span>, <span style="color:rgb(79,129,135)">a</span> + <span style="color:rgb(79,129,135)">b</span>)</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> temp</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p><p style="margin:0px;line-height:normal">
</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="font-family:arial,sans-serif;font-size:small">in this case, </span><span style="font-family:arial,sans-serif;font-size:small">because of </span><span style="font-family:arial,sans-serif;font-size:small">GeneratorType</span><span style="font-family:arial,sans-serif;font-size:small"> is clearly a </span><span style="font-family:arial,sans-serif;font-size:small">destructive iteration type </span><span style="font-family:arial,sans-serif;font-size:small">and CollectionType is </span><span style="font-family:arial,sans-serif;font-size:small">clearly a </span><span style="font-family:arial,sans-serif;font-size:small">multi-pass indexed type</span></p><p style="margin:0px;line-height:normal"><span style="font-family:arial,sans-serif;font-size:small">we should stop using the </span><span style="font-family:arial,sans-serif;font-size:small">SequenceType (or just rename it to _</span><span style="font-family:arial,sans-serif;font-size:small">SequenceType and tell people don't use it directly</span><span style="font-family:arial,sans-serif;font-size:small">) directly.</span><font face="Menlo"><span style="font-size:11px"> </span></font><span style="font-family:arial,sans-serif;font-size:small">we have the </span><span style="font-family:arial,sans-serif;font-size:small">GeneratorType which confirms </span><span style="font-family:arial,sans-serif;font-size:small">SequenceType already. </span>it can reduce confusion of SequenceType.</p></div></div></div>