[Python-ideas] x=(yield from) confusion [was:Yet another alternative name for yield-from]

Nick Coghlan ncoghlan at gmail.com
Tue Apr 7 23:59:34 CEST 2009

Jacob Holm wrote:
> So one @coroutine can't call another using yield-from. Why shouldn't it
> be possible? All we need is a way to avoid the first next() call and
> substitute some other value.
> Here is a silly example of two coroutines calling each other using one
> of the syntax-based ideas I have for handling this. (I don't care about
> the actual syntax, just about the ability to do this)
> @coroutine
> def avg2():
>    a = yield
>    b = yield
>    return (a+b)/2
> @coroutine
> def avg_diff():
>    a = yield from avg2() start None  # "start EXPR" means use EXPR for
> first value to yield instead of next()
>    b = yield from avg2() start a     # "start EXPR" means use EXPR for
> first value to yield instead of next()
>    yield b
>    return a-b

You can fix this without syntax by changing the way avg2 is written.

def avg2(start=None):
   a = yield start
   b = yield
   return (a+b)/2

def avg_diff(start=None):
   a = yield from avg2(start)
   b = yield from avg2(a)
   yield b
   return a-b

a = avg2()
a.send(43)   # raises StopIteration(42)

d = avg_diff()
d.send(2.0)  # returns from first yield-from, yields 1.5 as part of
starting second yield-from
d.send(4.0)  # returns from second yield-from. yields 3.5
d.next()     # returns from avg_diff. raises StopIteration(-2.0)

So it just becomes a new rule of thumb for coroutines: a yield-from
friendly coroutine will accept a "start" argument that defaults to None
and is returned from the first yield call.

And just like threading.Thread, it will leave the idea of defining the
coroutine and starting the coroutine as separate activities.


Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-ideas mailing list