<div dir="ltr">Hmm I see.<div><br></div><div>Do we have any example cases where returning nil repeatedly would require extra branches or state?</div><div><br></div><div>The generators in the standard library don&#39;t (*) – the usual pattern is either of the following: </div><div>- 1) Check state if we&#39;re at end, if so return nil 2) get return value 3) advance state. Since the state is not mutated before returning nil, repeating nil is automatic.</div><div>- 1) Call next() on one or more wrapped generators 2) return some transformation of that. If the wrapped generators repeat nil, repeating nil is also automatic for the wrapper.</div><div><br></div><div>If you would have a generator setup that doesn&#39;t automatically repeat nil, omitting a nil-repeat check might be dangerous considering the risk other code hadn&#39;t considered the case.</div><div><br></div><div>(*) StrideThroughGenerator &amp; ZipGenerator have a done flag, but need these even without repeating nil. JoinGenerator has an .End state but actually doesn&#39;t have to – even to repeat nil.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 3, 2016 at 8:12 PM, Dmitri Gribenko <span dir="ltr">&lt;<a href="mailto:gribozavr@gmail.com" target="_blank">gribozavr@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Wed, Mar 2, 2016 at 10:47 PM, Patrick Pijnappel via swift-evolution<br>
&lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt; Situation<br>
&gt; Currently GeneratorType.next() requires callers to not call next() after it<br>
&gt; has returned nil once, even encouraging a preconditionFailure() if this is<br>
&gt; violated:<br>
&gt;<br>
&gt;   /// - Requires: `next()` has not been applied to a copy of `self`<br>
&gt;   ///   since the copy was made, and no preceding call to `self.next()`<br>
&gt;   ///   has returned `nil`.  Specific implementations of this protocol<br>
&gt;   ///   are encouraged to respond to violations of this requirement by<br>
&gt;   ///   calling `preconditionFailure(&quot;...&quot;)`.<br>
<br>
</span>I&#39;d like to add more context to this discussion.  We added this<br>
requirement a while ago.  [1]  The reason for introducing it was not<br>
an attempt to flag bugs in client code.  Rather, we were not convinced<br>
that all generators can return nil repeatedly without loss of<br>
efficiency or extra storage burden.<br>
<br>
[1] <a href="https://github.com/apple/swift/commit/304b4f33ae74a5abd09da485bbc435dfa2ade522" rel="noreferrer" target="_blank">https://github.com/apple/swift/commit/304b4f33ae74a5abd09da485bbc435dfa2ade522</a><br>
and rdar://problem/17392226<br>
<span class=""><br>
&gt; Adds caller burden<br>
&gt; To avoid breaking the requirement, the caller will not uncommonly have to track extra state and branch<br>
<br>
</span>I would actually say the opposite -- running a non-trivial algorithm<br>
on generators is a very uncommon thing to do.  The 99% use case for<br>
generators is implicit usage from the for-in loop.  This is why<br>
allowing generators to be as simple as possible and pushing the<br>
requirement for extra branches into non-trivial algorithms made sense<br>
for us when we introduced this requirement.<br>
<span class=""><br>
&gt; Silent corner case<br>
&gt; Because basically all generators keep returning nil, it&#39;s not unlikely people will write their code based on the assumption it will always return nil<br>
<br>
</span>This is what concerns me the most about the current rules.<br>
<span class="HOEnZb"><font color="#888888"><br>
Dmitri<br>
<br>
--<br>
main(i,j){for(i=2;;i++){for(j=2;j&lt;i;j++){if(!(i%j)){j=0;break;}}if<br>
(j){printf(&quot;%d\n&quot;,i);}}} /*Dmitri Gribenko &lt;<a href="mailto:gribozavr@gmail.com">gribozavr@gmail.com</a>&gt;*/<br>
</font></span></blockquote></div><br></div>