[Python-Dev] PEP 380 (yield from a subgenerator) comments

P.J. Eby pje at telecommunity.com
Sun Mar 22 01:52:10 CET 2009

At 10:21 AM 3/22/2009 +1200, Greg Ewing wrote:
>P.J. Eby wrote:
>>My concern is that allowing 'return value' in generators is going 
>>to be confusing, since it effectively causes the return value to 
>>"disappear" if you're not using it in this special way with some 
>>framework that takes advantage.
>But part of all this is that you *don't* need a special
>framework to get the return value -- all you need is a
>caller that uses a yield-from statement. There are uses
>for that besides threading systems.

Such as?  I've been wracking my brain trying to come up with any 
*other* occasion where I'd need -- or even find it useful -- to have 
one generator yield the contents of another generator to its caller, 
and then use a separate return value in itself.  (I'm thus finding it 
hard to believe there's a non-contrived example that's not doing I/O, 
scheduling, or some other form of co-operative multitasking.)

In any case, you didn't address the confusion issue: the inability of 
generators to return a value is there for a good reason, and adding a 
return value that doesn't actually return anywhere unless you use it 
in a yield-from expression -- an expression that both looks like a 
statement and has control-flow side-effects -- seems both 
over-complex and an invitation to confusion.

This is different from plain yield expressions, in that plain yield 
expressions are *symmetric*: the value returned from the yield 
expression comes from the place where control flow is passed by the 
yield.  That is, 'x = yield y' takes value y, passes control flow to 
the caller, and then returns a result from the caller.  It's like an 
inverse function call.  'x = yield from y', on the other hand, first 
passes control to y, then the caller, then y, then the caller, an 
arbitrary number of times, and then finally returns a value from y, 
not the caller.

This is an awful lot of difference in control flow for only a slight 
change in syntax -- much more of a difference than the difference 
between yield statements and yield expressions.

So at present (for whatever those opinions are worth), I'd say -0 on 
a yield-from *statement* (somewhat useful but maybe not worth 
bothering with), +0 on a reference trampoline in the stdlib (slightly 
better than doing nothing at all, but not by much), and -1 on 
yield-from expressions and return values (confusing complication with 
very narrowly focused benefit, reasonably doable with library code).

More information about the Python-Dev mailing list