On Mon, Feb 16, 2009 at 8:53 PM, Greg Ewing
Guido van Rossum wrote:
There better be a pretty darn good reason to do this.
I think that making it easy to use generators as lightweight threads is a good enough reason.
I still expect that even with the new syntax this will be pretty cumbersome, and require the user to be aware of all sorts of oddities and restrictions. I think it may be better to leave this to libraries like Greenlets and systems like Stackless which manage to hind the mechanics much better. Also, the asymmetry between "yield expr" (which returns a value passed in by the caller using .send()) and "yield from expr" (which returns a value coming from the sub-generator) really bothers me. Finally, your PEP currently doesn't really do this use case justice; can you provide a more complete motivating example? I don't quite understand how I would write the function that is delegated to as "yield from g(x)" nor do I quite see what the caller of the outer generator should expect from successive next() or .send() calls.
I really don't like overloading return this way -- normally returning from a generator is equivalent to falling off the end and raises StopIteration
It still is. It's just that if you happen to return a value, it gets attached to the StopIteration for the use of anything that wants to care. It will make no difference at all to anything already existing.
So, "return" is equivalent to "raise StopIteration" and "return <value>" is equivalent to "raise StopIteration(<value>)"? I suppose I could live with that.
Also, if a generator that returns something gets called in a context that doesn't know about generator return values, the value is simply discarded, just as with an ordinary function call that ignores the return value.
I'm not sure I like this interpretation of .send() -- it looks asymmetrical with the way .send() to non-generator iterators is treated in other contexts, where it is an error.
I wouldn't object to raising an exception in that case. Come to think of it, doing that would me more consistent with the idea of the caller talking directly to the subgenerator.
And that could in turn be a generator with another such slot, right?
That's right.
Hopefully the testing for the presence of .throw, .send and .close could be done once at the start of the yield-from and represented as a set of flags.
Yes. You could even cache bound methods for these if you wanted.
I recommend that you produce a working implementation of this; who knows what other issues you might run into
Good idea. I'll see what I can come up with.
Sounds good. -- --Guido van Rossum (home page: http://www.python.org/~guido/)