[swift-evolution] [Proposal] Change guarantee for GeneratorType.next() to always return nil past end

Kevin Ballard kevin at sb.org
Sun Mar 6 20:16:54 CST 2016

On Sun, Mar 6, 2016, at 05:46 AM, Patrick Pijnappel wrote:
> My intuition says the extra state & branch needed for generators like TakeWhile could very well be optimized away in most cases if you dont make use of its post-nil behavior. Say TakeWhile is implemented as such:
> if done { return nil } guard let element = base.next() where
> predicate(element) else {  done = true  return nil } return element
> If the generator is then used in the common case:
> let generator = TakeWhileGenerator(...) while let element =
> generator.next() {  foo(element) }
> Should give us effectively:
> var base = ... let predicate = ... var done = false while true {  if
> done { break }  guard let element = base.next() where
> predicate(element) else {    done = true    break  }  foo(element) }
> The optimizer should see (or at least could see) `done` is never read
> after it's written to (thus removing the assignment), and therefore
> when checking the condition it can only be false (thus it can also be
> removed).

This may be doable for stdlib generators, but Swift currently has a
limitation where generic types/functions defined outside the current
file (or module with -whole-module-optimization) are only specialized
for their parameters if they come from the stdlib. Any such
types/functions defined in third-party libraries (or in other files if
you're not using -whole-module-optimization) use virtual dispatch on the
generic parameters instead. This means that any generic GeneratorTypes
defined in third-party libraries won't be able to optimize away this
check as it won't be able to tell that it isn't needed.

-Kevin Ballard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160306/3305d6ff/attachment.html>

More information about the swift-evolution mailing list