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

Kevin Ballard kevin at sb.org
Sat Mar 5 22:00:22 CST 2016

On Sat, Mar 5, 2016, at 05:40 PM, Brent Royal-Gordon wrote:
> > In fact, I don't think the post-nil behavior of generators is even the biggest potential gotcha. A much bigger issue is how generators behave when you make copies of them. If you ever copy a generator you're supposed to never touch the original again, but it's easy to violate that accidentally, and most generators actually behave sanely when copied anyway.
> That's true, but it's just not addressable until we have some kind of borrowing system in place.
> >> (Another reason to lean towards always returning `nil`: it's testable. In fact, I was thinking it might be nice to have something in XCTest where you could hand it a Sequence, or perhaps a closure that creates one, and an array containing the values you expect it to have, and it would assert the basic properties we expect from a Sequence, like that the elements come out in the right order, it returns nil at the end, `underestimateCount()` is not incorrect, etc. The `nil` semantic, unlike the other possible ones, is something you could include in that test.)
> > 
> > Defining the post-nil behavior as implementation-defined means that, by definition, you don't need to test how arbitrary generators behave there.
> True, but then you're imposing a constraint on the clients of generators: "Don't call next() again after it turns nil".

Sure, but as I've already stated, I believe very few people ever write code that depends on post-nil behavior anyway. In fact, it wouldn't surprise me to learn that far more people have to deal with this case while writing their own GeneratorTypes than there are people who hit this merely by using pre-existing GeneratorTypes.

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

-Kevin Ballard

More information about the swift-evolution mailing list