[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: A plea for a new old language
At 11:39 AM -0400 5/8/03, Anton van Straaten wrote:
>Dan Sugalski wrote:
>> I just spent part of last night and a bit of this morning putting
>> together a layman's explanation of continuation passing style.
>Neel Krishnaswami wrote:
>> However, I'm not sure why you feel the need to use CPS.
>It looks like Dan really needs to write a "layman's" motivation for the use
>of CPS in Parrot. If the reasons it presents justify the use of CPS, and if
>it's sufficiently accessible to its target audience of potential Parrot VM
>developers who haven't previously encountered CPS, the document itself will
>help decide the issue.
That's a good point. So, quickly, here goes.
What I'm considering is changing parrot's calling conventions such
that it is *mandatory* that the caller pass in a continuation
representing the caller's return location, rather than just pushing
the return address onto the stack. Right now when you dispatch to a
sub or method the engine pushes a return address onto the control
stack, and a return from a sub pops off that address and jumps there.
The caller is entirely responsible for saving its environment, and
the callee is responsible for making sure the stacks are cleaned up.
This can be something of an issue, as there's a fair amount of stuff
to tend to. The caller needs to save off the current lexical variable
chain head, the global variable chain head (we need to handle the
lexical masking of global variables for Python), and the current
opcode function table pointer. The callee needs to make sure the
stacks don't have any extra or missing entries/frames.
Going CPS makes calling easier. Rather than a half-dozen "push this
thing" ops, a call, and then a bunch of "pop this thing" ops, it's
just "make CPS thingie", call. And on the callee end there's no need
to track the number of elements/frames pushed onto a stack so they
get popped at the end, you just invoke the CPS thingie and the stacks
are put back in the state they were when the call was made.
It does conceptually simplify things, and thinking about it it
actually makes long-term expansion of the VM with backward
compatibility easier, since if there are more lexically scoped things
added later (say, event mask/level, or IO filters, or something) old
code will still preserve them right on a call since the "make CPS
thingie" op would get beefed up to know about the new things, so the
called function can mess around with them and not affect the calling
The one issue that this does raise is "how do you affect the caller",
since what if you *want* to affect the lexical chain or op function
table of the caller? Though I suppose we could allow you to mess with
the data stored in the CPS widget.
Does this make sense to anyone?
--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
firstname.lastname@example.org have teddy bears and even
teddy bears get drunk