<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=""><div class="">+1 from me on the grounds that I had no idea that this was an expectation of GeneratorType.next(), so yeah; all my generators currently return `nil` infinitely past the end. Does anyone know the history of this requirement? Perhaps it’s a newer one and I didn’t notice it being added?</div><div class=""><br class=""></div><div class="">The only advantage to a failure vs continuing nil that I can think of is if the generator is returning an optional type anyway; if the developer doesn’t check correctly for nil from the generator vs a stored value of nil then they could end up with an infinite loop, but this seems unlikely given that they’d be dealing with a type of Element?? rather than Element?, so whatever they’re doing with the results should fail due to type mismatches anyway.</div><div class=""><br class=""></div><div class="">So yeah, there’s possibly (and I stress possibly) a narrow case in which failure might catch a bug, but in most cases the optional behaviour should be enough, and the generator itself should be handling indices correctly internally to prevent issues with stepping past .endIndex etc.</div><br class=""><div><blockquote type="cite" class=""><div class="">On 3 Mar 2016, at 06:47, Patrick Pijnappel via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class=""><font face="arial, helvetica, sans-serif" class=""><b class="">Situation</b></font></div><div class=""><font face="arial, helvetica, sans-serif" class="">Currently </font><font face="monospace, monospace" class="">GeneratorType.next()</font><font face="arial, helvetica, sans-serif" class=""> requires callers to not call </font><font face="monospace, monospace" class="">next()</font><font face="arial, helvetica, sans-serif" class=""> after it has returned </font><font face="monospace, monospace" class="">nil</font><font face="arial, helvetica, sans-serif" class=""> once, even encouraging a </font><font face="monospace, monospace" class="">preconditionFailure()</font><font face="arial, helvetica, sans-serif" class=""> if this is violated:</font></div><div class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(181, 181, 181);" class=""><span style="color:rgb(66,66,66)" class=""> </span>/// - <span style="color:rgb(121,121,121)" class="">Requires</span>: `next()` has not been applied to a copy of `self`</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(181, 181, 181);" class=""><span style="color:rgb(66,66,66)" class=""> </span>/// since the copy was made, and no preceding call to `self.next()`</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(181, 181, 181);" class=""><span style="color:rgb(66,66,66)" class=""> </span>/// has returned `nil`. Specific implementations of this protocol</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(181, 181, 181);" class=""><span style="color:rgb(66,66,66)" class=""> </span>/// are encouraged to respond to violations of this requirement by</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(181, 181, 181);" class=""><span style="color:rgb(66,66,66)" class=""> </span>/// calling `preconditionFailure("...")`.</div><div class=""><div class=""><font face="arial, helvetica, sans-serif" class=""><br class=""></font></div><div class=""><font face="arial, helvetica, sans-serif" class="">However, all </font><font face="arial, helvetica, sans-serif" class="">28 GeneratorTypes in the standard library</font><span style="font-family:arial,helvetica,sans-serif" class=""> actually do return nil on repeated calls past the end.</span><br class=""></div><div class=""><span style="font-family:arial,helvetica,sans-serif" class=""><br class=""></span></div><div class=""><span style="font-family:arial,helvetica,sans-serif" class=""><br class=""></span></div><div class=""><font face="arial, helvetica, sans-serif" class=""><b class="">Silent corner case</b></font></div><div class=""><span style="font-family:arial,helvetica,sans-serif" class="">Because basically all generators keep returning nil, it'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 class=""><br class=""></div><div class=""><font face="arial, helvetica, sans-serif" class=""><b class="">Adds caller burden</b></font></div><div class=""><span style="font-family:arial,helvetica,sans-serif" class="">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 & UTF-16 decoders do this (incidentally introducing an extra branch into a hot code path), while the UTF-32 decoder doesn't actually check – passing the requirement on to its caller (without this being documented). From personal experience implementing several custom generators I've found that respecting the requirement invariably adds complexity to the implementation.</span></div><div class=""><br class=""></div><div class=""><font face="arial, helvetica, sans-serif" class=""><b class="">Doesn't prevent bugs</b></font></div><div class=""><span style="font-family:arial,helvetica,sans-serif" class="">There seems to be little advantage to having it crash on past-the-end calls to next(). So far I haven't seen any examples where not crashing would silently hide a bug – and again even if there was it wouldn't help much considering almost no generators actually do crash.</span></div><div class=""><div class=""><br class=""></div><div class=""><font face="arial, helvetica, sans-serif" class=""><b class=""><br class=""></b></font></div><div class=""><font face="arial, helvetica, sans-serif" class=""><b class="">Proposal</b></font></div></div></div><div class="">Change the guarantee for GeneratorType.next() to keep returning nil indefinitely after it has been exhausted.</div></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>