Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can Python coroutines not be called recursively?

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?

like image 859
gens Avatar asked Oct 29 '25 09:10

gens


1 Answers

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.

like image 147
user2357112 supports Monica Avatar answered Oct 31 '25 10:10

user2357112 supports Monica



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!