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

Patrick Pijnappel patrickpijnappel at gmail.com
Sun Mar 6 07:46:47 CST 2016


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).

I don't have a machine to test this on atm though.


On Sunday, 6 March 2016, Brent Royal-Gordon via swift-evolution <
swift-evolution at swift.org> wrote:

> >> I think it will be far easier to write generic tests of any generator
> than it will be to write generic tests of any function that *uses* a
> generic generator.
> >>
> >> (Although I suppose you could assist in that testing by writing a
> wrapper around any sequence/collection/generator which enforces all rules
> as strictly as possible.)
> >
> > You could always just test the behavior of the FuseGenerator wrapping
> it, if you really want to be able to rely on always-returning-nil behavior.
> But I'm not sure what tests you'd write that even hits this case, except
> for a test that's designed specifically to test the post-nil behavior
> (which we've already established isn't necessary to check for arbitrary
> generators if GeneratorType leaves that as implementation-defined).
>
> The fuse generator wouldn't do what I'm talking about. What I mean is that
> it might be useful for testing purposes to be able to wrap a
> collection/sequence in a StrictCollection/StrictSequence (with
> corresponding StrictGenerators, StrictIndexes,etc.) which would do things
> like:
>
> * Detect if you copy a generator and then use both copies
> * Detect if you call next() on a generator after it returns nil
> * StrictCollection only: Invalidate all indices retrieved before any
> mutation
> * StrictSequence only: Prevent you from making a generator more than once
>
> The idea is that, when you're writing a piece of code that's generic on
> any collection or sequence type, your unit tests could pass in a
> StrictCollection/StrictSequence-wrapped version of whatever your actual
> data is, and if your code doesn't crash you can be pretty sure it's not
> violating any of those protocols' unevenly enforced requirements.
>
> --
> Brent Royal-Gordon
> Architechies
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <javascript:;>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160307/1a327cf2/attachment.html>


More information about the swift-evolution mailing list