[Python-Dev] Stackless pages

Gordon McMillan gmcm@hypernet.com
Mon, 6 Nov 2000 09:54:57 -0500

Jeremy wrote:

> ...  I think we would do well to
> purposefully omit continuations from the Python language.  There seems
> to be little need for a facility to implement arbitrary control
> structures in Python.  If Python support coroutines and microthreads,
> I am not sure what else would be needed.

I'm not sure what you mean here. So far, no one has asked for 
anything to get added to the *language* (although generators 
and coroutines could be made nicer with a bit of keyword 
support, it's not necessary).
> It would be very helpful if the PEPs on Stackless could address this
> issue.  One way to address it is to ask these questions: What new
> control structures do users want in Python?  How best can they be
> implemented?  Are continuations necessary to implement them or are
> there other options?

If by "control structure" you mean for / while / do type things, 
well, Python's not a functional language, and stackless / 
continuations won't grow you any new ones.

OTOH, if threads added new "control structures", then yes, 
continuations adds new ones (although from a language 
viewpoint, they don't look like anything new).
> The sort of implementation complexity that I worry about with
> Stackless is, e.g. clean interaction with the C stack.  If a Python C
> API call is made that pushes a C stack frame, e.g. PyObject_Compare,
> then a continuation stored before that call can no longer be invokved.

You mean when C code (called by Python) ends up calling 
eval_code2, and the Python code so invoked wants to use a 
continuation which "resides" in some other invocation of 
eval_code2? Yes, Christian gives you an error at that point (I 
believe; I've never stumbled on this personally).

> The problem is that continuations break the notion a C API call will
> always return an answer; they create a situation in which the C call
> that is made should never return, because control is transferred to
> the continuation. 

Well, sys.exit breaks that notion too :-). If an API says that a 
return is required, it's a programmer error not to return 

I think it's universally agreed that there should be a "coroutine" 
API. Perhaps it is best done from scratch, or perhaps it is to 
the continuation module as threading is to thread. But I think 
Greg Ewing is right - it doesn't make much difference as far as 
stackless is concerned.

> I assume Stackless raises an error in this case,
> but this seems pretty messy: How do we right a language spec that
> explains when an error will occur without appealing to the
> language implementation?

I'm not understanding. 

In practical terms, I toasted my machine more times and more 
thoroughly playing with the thread module than I have with the 
continuation module. In that respect, continuations are a good 
deal safer - they don't have any effect on the state of your OS.

If you're playing with the raw "go-to" features of the 
continuation module, it's very easy to screw up. That's simply 
because code has to "balance", somehow. Call and return are 
the universally accepted way of doing that in the procedural 
community. But they're just a protocol based on go-to. The go-
to is still there, even if it's in the chip's microcode.

Christian's continuation module exposes a bunch of primitives. 
Most of the material on the pages I put up is concerned with 
how to mix and match those to get useful results (one 
example is coded 6 different ways). No one thinks this is a 
good "end state", just like the thread module was a lousy "end 
state".  But we can't steal Java's API here, and we can't steal 
from functional languages either, 'cause Python just ain't 

Everybody wants to see safer ways of using this stuff, but 
there's still a lot of experimenting to do. And I, for one, don't 
want to slam the door after one or two safe ways have been 
found. (And personally, I've found most of the attempts at, e.g. 
writing a "coroutine" class, less comprehensible than using 
the primitives directly.)

- Gordon