<div dir="ltr"><div><font face="arial, helvetica, sans-serif"><b>Situation</b></font></div><div><font face="arial, helvetica, sans-serif">Currently </font><font face="monospace, monospace">GeneratorType.next()</font><font face="arial, helvetica, sans-serif"> requires callers to not call </font><font face="monospace, monospace">next()</font><font face="arial, helvetica, sans-serif"> after it has returned </font><font face="monospace, monospace">nil</font><font face="arial, helvetica, sans-serif"> once, even encouraging a </font><font face="monospace, monospace">preconditionFailure()</font><font face="arial, helvetica, sans-serif"> if this is violated:</font></div><div><br></div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(181,181,181)"><span style="color:rgb(66,66,66)">  </span>/// - <span style="color:rgb(121,121,121)">Requires</span>: `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(181,181,181)"><span style="color:rgb(66,66,66)">  </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(181,181,181)"><span style="color:rgb(66,66,66)">  </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(181,181,181)"><span style="color:rgb(66,66,66)">  </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(181,181,181)"><span style="color:rgb(66,66,66)">  </span>///   calling `preconditionFailure(&quot;...&quot;)`.</p><div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">However, all </font><font face="arial, helvetica, sans-serif">28 GeneratorTypes in the standard library</font><span style="font-family:arial,helvetica,sans-serif"> actually do return nil on repeated calls past the end.</span><br></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><font face="arial, helvetica, sans-serif"><b>Silent corner case</b></font></div><div><span style="font-family:arial,helvetica,sans-serif">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 (breaking the requirement) and that will almost always work – until someone passes in a GeneratorType that actually does raise the recommended preconditionFailure(). It becomes a silent corner case.</span></div><div><br></div><div><font face="arial, helvetica, sans-serif"><b>Adds caller burden</b></font></div><div><span style="font-family:arial,helvetica,sans-serif">To avoid breaking the requirement, the caller will not uncommonly have to track extra state and branch (e.g. keep a done/atEnd boolean). For example the UTF-8 &amp; UTF-16 decoders do this (incidentally introducing an extra branch into a hot code path), while the UTF-32 decoder doesn&#39;t actually check – passing the requirement on to its caller (without this being documented). From personal experience implementing several custom generators I&#39;ve found that respecting the requirement invariably adds complexity to the implementation.</span></div><div><br></div><div><font face="arial, helvetica, sans-serif"><b>Doesn&#39;t prevent bugs</b></font></div><div><span style="font-family:arial,helvetica,sans-serif">There seems to be little advantage to having it crash on past-the-end calls to next(). So far I haven&#39;t seen any examples where not crashing would silently hide a bug – and again even if there was it wouldn&#39;t help much considering almost no generators actually do crash.</span></div><div><div><br></div><div><font face="arial, helvetica, sans-serif"><b><br></b></font></div><div><font face="arial, helvetica, sans-serif"><b>Proposal</b></font></div></div></div><div>Change the guarantee for GeneratorType.next() to keep returning nil indefinitely after it has been exhausted.</div></div>