[Python-Dev] PEP 380 (yield from a subgenerator) comments
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