[Python-ideas] Cofunctions - Getting away from the iterator protocol

Greg Ewing greg.ewing at canterbury.ac.nz
Thu Nov 3 02:47:41 CET 2011


On 03/11/11 05:21, Ron Adam wrote:

> Would it be possible to rewrite the 'yield' internals so they work in
> the following way...
>
>       # a = yield b
>       try:
>            raise SuspendException(b, _self=_self)
>       Except ContinueException as exc:
>            a = exc.args

I've just been thinking about something like that, while pondering
whether there is a middle ground somewhere between the yield-from
mechanism and a completely new coroutine protocol.

The problem I had with building all of it on yield-from was that
there was no way to distinguish a 'yield' being used for the purpose
of suspending a coroutine from one being used to return a value
to a next() call.

However, if something other than 'yield' is used for coroutine
suspension -- such as a 'coyield' keyword or coyield() function --
then I think this problem becomes solvable. In a cogenerator
(i.e. a generator running in coroutine mode), 'coyield' would
do what 'yield' does in normal mode (simply suspend the frame),
and 'yield(value)' would raise StopIteration(value).

(If the latter seems unintuitive, I sympathise. It arises because
we're effectively making a cocall to the __next__ method of the
generator, and in the yield-from universe, the way a cocall
returns a value is by raising StopIteration.)

But now we need a different way for the cogenerator to signal
that it has finished iterating! I think what will need to happen
is that a cogenerator raises CoStopIteration instead of
StopIteration when it falls off the end, and the cocaller of
the cogenerator catches that and turns it into a normal
StopIteration.

Confused enough yet? I had better finish my cosandwitch and get
some more cocoffee before trying to think about this any more...

-- 
Greg



More information about the Python-ideas mailing list