[Python-ideas] yield-from and @coroutine decorator [was:x=(yield from) confusion]
Jacob Holm
jh at improva.dk
Sat Apr 4 01:34:16 CEST 2009
Nick Coghlan wrote:
> Jacob Holm wrote:
>
>> We should probably drop that particular bikeshed discussion until we
>> actually know the details of what the construct should do, esp in the
>> context of close(). I am starting to lose track of all the different
>> possible versions.
>>
>
> Note that the syntax for returning values from generators is largely
> independent of the semantics. Guido has pointed out that disallowing the
> naive "return EXPR" in generators is an important learning tool for
> inexperienced generator users, and I think he's right.
>
I agree that a separate syntax for returning a value from a
generator/coroutine is propably a good idea. (I am still not convinced
we need a separate exception for it, but that is a separate
discussion). I even think it would be a good idea to deprecate the use
of the normal "return" in generators, but that is probably not going to
happen.
> "return finally" reads pretty well and doesn't add a new keyword, while
> still allowing generator return values to be written easily. I haven't
> seen other suggestions I particularly like, so I figured I'd run with
> that one for the revised example :)
>
You can call it whatever you want, as long as it works predictably for
the use cases we are finding.
[snip]
>> Now for my problem. The original averager example was inspired by the
>> tutorial http://dabeaz.com/coroutines/ that Guido pointed to. (Great
>> stuff, btw). One pattern that is recommended by the tutorial and used
>> throughout is to decorate all coroutines with a decorator like:
>>
>> def coroutine(func):
>> def start(*args,**kwargs):
>> cr = func(*args,**kwargs)
>> cr.next()
>> return cr
>> return start
>>
>>
>> The idea is that it saves you from the initial next() call used to start
>> the coroutine. The problem is that you cannot use such a decorated
>> coroutine in any flavor of the yield-from expression we have considered
>> so far, because the yield-from will start out by doing an *additional*
>> next call and yield that value.
>>
>> I have a few vague ideas of how we might change "yield from" to support
>> this, but nothing concrete enough to put here. Is this a problem we
>> should try to fix, and if so, how?
>>
>
> Hmm, that's a tricky one. It sounds like it is definitely an issue the
> PEP needs to discuss, but I don't currently have an opinion as to what
> it should say.
>
Here is one possible fix, never mind the syntax. We could change the
yield from expression from the current:
RESULT = yield from EXPR
by adding an extra form, possibly one of:
RESULT = yield STARTEXPR from EXPR
RESULT = yield from EXPR with STARTEXPR
RESULT = yield from EXPR as NAME starting with STARTEXPR(NAME)
And letting STARTEXPR if given take the place of the initial _i.next()
in the expansion(s). The point is we need to yield *something* first,
before rerouting all send(), next() and throw() calls to the subiterator.
>> not-trying-to-be-difficult-ly yours
>>
>
> We have a long way to go before we even come close to consuming as many
> pixels as PEP 308 or PEP 343 - a fact for which Greg is probably grateful ;)
>
Him and everybody else I would think. But AFAICT we are not even close
to finished, so we may get there yet.
- Jacob
More information about the Python-ideas
mailing list