On Fri, Nov 21, 2014 at 8:53 AM, Chris Barker
As someone who has written maybe one generator expression in production code, I have little opinion on the PEP.
But as someone that teaches Python, I have a comment on:
On Fri, Nov 21, 2014 at 10:50:52PM +1100, Chris Angelico wrote:
Yes, this would be affected. This proposal causes a separation of generators and iterators, so it's no longer possible to pretend that they're the same thing.
As pointed out by Steven, the _are_ the same thing. When I teach interators and generators, I get a bit tangled up explaining what the difference is, and why Python has both. This is what I say:
Conceptually ( outside of language constructs):
An "generator" is something that, well, generates value on the fly, as requested, until there are no more to generate, and then terminates.
A "iterator" on the other had is something that produces the values in a pre-existing sequence of values, until there are no more.
IN practice, python uses the exact same protocol (the iterator protocol -- __iter__, __next__) for both, so that you can write, e.g. a for loop, and not have to know whether the underlying object you are looping through is iterating or generating...
As you can write a "generator" in the sense above in a class that supports the iterator protocol (and, can, in fact, write an "iterator" with a generator function), then I say that generator functions really are only syntactic sugar -- they are short and sweet and do much of the book keeping for you.
But given all that keeping the protocols as similar as possible is a *good* thing, not a bad one -- they should behave as much as possible teh same.
If StopIteration bubbles up from inside an iterator, wouldn't that silently terminate as well?
Honestly, I'm a bit lost -- but my point is this -- generators and iterators should behave as much the same as possible.
I'm sorry you see it that way; we must have done a terrible job explaining this in the past. :-( The behavior for the *consumer* of the iteration is unchanged (call next() until it raises StopIteration -- or let a for-loop take care of the details for you). The interface for the *producer* has never been all that similar: In a generator you *yield* subsequent values until you are done; but if you are not using a generator, you must define a __next__() method (next() in Python 2) that *returns* a single value each time, until it's done, and then it has to raise StopIteration. There is no need to raise StopIteration from a generator, you just return when you are done. Insisting that raising StopIteration in a generator makes it more similar to a __next__() method ignores the fact that producing values is done in a completely different ways. So, again, the PEP does not change anything about iterators, and generators will continue to follow the iterator protocol. The change is only for generator authors (and, most importantly, for people using a certain hack in generator expressions). -- --Guido van Rossum (python.org/~guido)