[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 
function.

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?
-- 
                                         Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski                          even samurai
dan@sidhe.org                         have teddy bears and even
                                       teddy bears get drunk