[Python-Dev] Re: [python-coro] coroutines and microthreads
Just van Rossum
just@letterror.com
Fri, 17 Nov 2000 09:55:48 +0100
At 7:42 PM -0500 16-11-2000, Guido van Rossum wrote:
[ snipp ]
>Using my proposed API this example could be rewritten a bit
>cleaner, as follows:
>
> from coro import coroutine, suspend, EarlyExit # Provisional module name
>
> def fringe(L):
> for x in L:
> if type(x) is type(L):
> fringe(x)
> else:
> suspend(x)
>
> def printinorder(L):
> c = coroutine(f, L)
> try:
> while 1:
> print c(),
> except EarlyExit:
> pass
> print
>
> x = [0, 1, [2, [3]], [4,5], [[[6]]]]
> printinorder(x) # prints "0 1 2 3 4 5 6"
>
>This is about as simple as it gets. It supports both generators (like
>the example here) and coroutines (like Tim's Demo/threads/squasher.py
>example).
Neat! (It's _very_ close to what I proposed myself, so how can I not like
it? ;-)
One question: I assume values can also be passed when explicitly resuming a
coroutine. However, the _first_ time a coroutine is "resumed" (started,
really), the stored init arguments get passed to the function. What to do
with a value passed to the resume call? Two possible solutions:
1) don't not allow passing a value the first time
2) add the value(s) to the init arguments
As code:
def fribble(initarg):
...
c = coroutine(fribble, initarg)
c(x) # <-- where does x go? or is it not allowed?
>Besides the APIs shown here (coroutine(), suspend(), and EarlyExit) I
>propose a function current() which returns the current coroutine
>object.
Starts looking more and more like what I proposed myself...
>There should also be a way to kill a coroutine (or at least
>to send an exception). When a coroutine falls through at its end,
>*some* other coroutine needs to be resumed.
Here's what I did in my own strawman:
- resume the guy that resumed me, if any (making it equivalent to suspend())
- if we were resumed by a suspend() call (which in my proposal means we
don't have a "resumer", to avoid endless suspend()/suspend() bouncing),
resume the "main" coroutine, which is the (non-coro) code that started the
first coroutine.
Maybe coroutines should have a kill() method, which would post the
EarlyExit exception. Maybe even a postException() method (like uthreads
have), allowing you to post arbitrary exceptions to the coroutine. Dunno.
>I believe this can be implemented with a much simplified stackless
>approach, that doesn't cater towards continuations (but still borrows
>a lot of wisdom from Christian's Stackless). It can also be
>implemented using threads, which should give some hope for getting the
>same API supported in JPython, making it more attractive. I am hoping
>to create an implementation on top of Stackless, just to experiment
>with the idiom.
Here's my own code, based on stackless 1.1:
http://www.petr.com/just/corojust.tar.gz
or
http://www.petr.com/just/corojust/
for the individual files.
Apart from the initialisation it's pretty much what you propose.
Just