> Now to the main point. When a generator function is run, it immediately > returns a generator, and it does not run any code inside the generator. > Not until generator.next() is called is any code inside the generator > executed, giving it traditional lazy evaluation semantics. Why don't > generators follow the usual eager evaluation semantics of Python and > immediately execute up until right before the first yield instead? > Giving generators special case semantics for no good reason is a really > bad idea, so I'm very curious if there is a good reason for it being > this way. With the current semantics it means that errors can pop up at > unexpected times rather than the code failing fast.
The semantics of a generator are very clear: on .next(), run until the next yield is reached and then return the yielded value. Plus of course the dealing with StopIteration-stuff. Your scenario would introduce a special-case for the first run, making it necessary to keep additional state around (possibly introducing GC-issues on the way), just for the sake of it. And violate the lazyness a generator is all about. Think of a situation like this: def g(): while True: yield time.time() Obviously you want to yield the time at the moment of .next() being called. Not something stored from ages ago. If anything that setups the generator shall be done immediatly, it's easy enough: def g(): first_result = time.time() def _g(): yield first_result while True: yield time.time() return _() Diez -- http://mail.python.org/mailman/listinfo/python-list