|
|
|
|
|
by anon4
4443 days ago
|
|
Yield and generators (i.e. save stack; return value to caller; receive value from caller) are really a language feature for writing a runtime for a different language with coroutines. Or if you're willing to write your program in a way that looks like it was generated by a source-to-source transformation tool, you can write your coroutines on top of them. The most basic construct is something like this: CurrentCoroutine = None
def run(main, arg):
global CurrentCoroutine
CurrentCoroutine = main
while CurrentCoroutine is not None
CurrentCoroutine, arg = CurrentCoroutine.send(arg)
def corodecorator(coro):
@functools.wraps(coro):
def init():
c = coro()
c.next()
return c
return init
And this is pretty much it. A simple example for two coroutines that pass control to each other would be: @corodecorator
def coro1():
# yield nothing on first call to receive args
arg = yield None
friend = arg[0]
while True:
print('coro1')
arg = yield friend, (CurrentCoroutine,)
friend = arg[0]
@corodecorator
def coro2():
arg = yield None
friend = arg[0]
while True:
print('coro2')
arg = yield friend, (CurrentCoroutine,)
friend = arg[0]
run(coro1(), (coro2(),))
You can do the same with javascript and events, but it requires a much higher degree of masochism. |
|