[Stackless] Stackless-like module on Scheme continuations.

Esteban U. Caamano Castro euccastro at yahoo.com
Sat Aug 25 18:34:20 CEST 2007

I did this for a personal project. It's an implementation of a simplified Stackless-like API [1] on top of Scheme continuations.


I post this both as a curiosity and to ask what you think about the API.  In Stackless terms, it would be as if we had

(add-next-task! thunk) 
    Equivalent to stackless.tasklet(thunk)(), but it schedules the tasklet *right next* after the current one yields or blocks (I don't know if this is the case with Stackless too.) This is so you can implement other behaviours with no further calls: if you want to switch immediately to the scheduled tasklet, you just yield right after calling this. If you want the tasklet to be scheduled _after_ the currently scheduled ones, you just yield first thing in the thunk.

    Equivalent to lambda: stackless.getruncount() == 1

    Equivalent to stackless.schedule()

(make-channel) -> channel
    Equivalent to stackless.channel()

(send-to-channel! channel value)
    Equivalent to channel.send(), but if there is a receiver waiting it doesn't block (I can't remember if this is the case with Stackless), and it schedules the receiver to run *right next* after the current task yields or blocks.

(receive-from-channel! channel) -> sent value
    Equivalent to channel.receive(), with similar scheduling semantics as above.

(channel-sending? channel) -> bool
    Equivalent to lambda channel: channel.balance > 0

(channel-receiving? channel) -> bool
    Equivalent to lambda channel: channel.balance < 0

Of course Stackless offers more than this.  Most notably, this doesn't try to do preemptive scheduling at all, and whether and how this plays with C extensions is (Scheme) implementation dependent.  Barring that, I haven't found anything I need that can't be built on top of these[2].  For example, I provide no way to get hold of a reference to a tasklet, but I'm not sure why would I need that. Other example: stackless.run() is defined as an utility function that does the equivalent of

while stackless.getruncount() > 1:

Do you think the Stackless API could be defined, for most useful purposes, with the calls above?  If not, what relevant use cases can you think of, which are not supported by this?


P.S.: I know that the Stackless API, like Python in general, tries to be practical rather than minimalistic.  I'm not criticising that; I'm only trying to identify the minimal interface required to expose all the functionality you need.

[1] I mean the Python, not the C, API.
[2] Barring channel.send_exception() and pickling stuff, which have no portable counterpart in Scheme.

Stackless mailing list
Stackless at stackless.com

More information about the Stackless mailing list