Date: 2009-02-05 07:45:00
Tags: psil, stackless, continuations
continuations using stackless python

I've been pondering about how to implement continuations in my Psil interpreter. One choice is to redesign the whole thing to use continuation-passing style with the resulting performance hit. I've been putting off trying to do that.

It occurred to me to have a look at Stackless, which is a variant of Python that supports lightweight threads called "tasklets". It turns out this is ideal. Here is the complete implementation of continuations:

    def call_with_current_continuation(f):
        import stackless
        channel = stackless.channel()
        stackless.tasklet(f)(channel.send)
        return channel.receive()

That's it! Calling stackless.tasklet() creates a new tasklet object that will be scheduled later by Stackless. The function f is expected to take one parameter, which is itself a function that takes one parameter that will be returned from call_with_current_continuation. It turns out that channel.send is exactly such a function (bound member functions in Python are great). Then calling channel.receive() stops the current tasklet and waits for the new one to call channel.send with a parameter. Finally, the value is returned from call_with_current_continuation.

It took me a while to come up with this concise implementation, after reading the sparse Stackless documentation and tutorial. I had to let the concept of continuations and the philosophy of Stackless sink in a bit before this implementation became clear. I'm quite pleased with it.

[info]taral
2009-02-04T18:49:09Z
Nifty. You might want to note that these are one-shot continuations.
[info]ghewgill
2009-02-04T18:51:10Z
Ooh, good point. I'll have to work on that.
[info]ghewgill
2009-02-07T09:09:47Z
I found that the Stackless paper goes into a lot of detail about resuable continuations. I'm sure there is something in there that does what I want to do.
[info]pne
2009-02-05T11:56:31Z
(bound member functions in Python are great)

And being able to pass around (references to) functions, store them in data structures, etc. are also great. I miss that in my day job programming Java.
Greg Hewgill <greg@hewgill.com>