[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