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...