Nick Coghlan wrote:
The limitation of Lua style coroutines is that they can't be suspended from inside a function implemented in C. Without greenlets/Stackless style assembly code, coroutines in Python would likely have the same limitation.
PEP 3152 (and all generator based coroutines) have the limitation that they can't suspend if there's a *Python* function on the stack. Can you see why I know consider this approach categorically worse than one that pursued the Lua approach?
Ouch, yes, point taken. Fortunately, I think I may have an answer to this...
Now that the cocall syntax is gone, the bytecode generated for a cofunction is actually identical to that of an ordinary function. The only difference is a flag in the code object.
If the flag were moved into the stack frame instead, it would be possible to run any function in either "normal" or "coroutine" mode, depending on whether it was invoked via __call__ or __cocall__.
So there would no longer be two kinds of function, no need for 'codef', and any pure-Python code could be used either way.
This wouldn't automatically handle the problem of C code -- existing C functions would run in "normal" mode and therefore wouldn't be able to yield. However, there is at least a clear way for C-implemented objects to participate, by providing a __cocall__ method that returns an iterator.