Question

I have been using Python coroutines instead of threading with some success. It occurred to me that I might have a use for a coroutine that knows about itself, so it can send itself something. I found that this is not possible (in Python 3.3.3 anyway). To test, I wrote the following code:

def recursive_coroutine():
    rc = (yield)
    rc.send(rc)

reco = recursive_coroutine()
next(reco)
reco.send(reco)

This raises an exception:

Traceback (most recent call last):
  File "rc.py", line 7, in <module>
    reco.send(reco)
  File "rc.py", line 3, in recursive_coroutine
    rc.send(rc)
ValueError: generator already executing

Although the error is clear, it feels like this should be possible. I never got as far as to come up with a useful, realistic application of a recursive coroutine, so I'm not looking for an answer to a specific problem. Is there a reason, other than perhaps implementation difficulty, that this is not possible?

Was it helpful?

Solution

This isn't possible because for send to work, the coroutine has to be waiting for input. yield pauses a coroutine, and send and next unpause it. If the generator is calling send, it can't simultaneously be paused and waiting for input.

If you could send to an unpaused coroutine, the semantics would get really weird. Suppose that rc.send(rc) line worked. Then send would continue the execution of the coroutine from where it left off, which is the send call... but there is no value for send to return, because we didn't hit a yield.

Suppose we return some dummy value and continue. Then the coroutine would execute until the next yield. At that point, what happens? Does execution rewind so send can return the yielded value? Does the yield discard the value? Where does control flow go? There's no good answer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top