KBD

Keith Devens .com

Sunday, July 20, 2008 Flag waving
"It's no trick for talented people to be interesting, but it's a gift to be interested. We want... – Randy S. Nelson (dean of Pixar University)
← Joe WilsonECMAScript for XML →

Daily link icon Sunday, July 11, 2004

Understanding continuations

Surprisingly, I think this continuation sandwich example (via the Perl 6 summary) has been more helpful in helping me understand continuations than anything else I've read so far. I already had a half-understanding, and this pushed me over to a three-quarters-understanding.

My understanding of continuations stands as follows: With closures, you create a function that wraps any lexicals in scope at the time which then travel along with the function wherever it goes. A continuation is similar, except rather than operating within the scope of a function, it operates on the scope of the entire program, wrapping all program state and carrying it around with it.

My main problem up until now has been that "The continuation can't just save all data associated with the program, that's crazy!". So I assume it must be part of some kind of copy-on-write scheme, where a continuation (probably similar to how closures wrap their lexicals) references the same variables as the main program does until one of those variables changes in the main program or in the continuation, at which point someone splits off a new variable that has the new value and is separate from the old variable.

The only issue is that I don't understand how this would work. Say you save 5 continuations at some point in the program. If you change a variable inside one of the continuations it splits off a new variable and doesn't share the same variable with the other four anymore. But, is the main program sort of like its own continuation, so if you change a variable in the main program it splits off a brand new one for itself? Furthermore, won't each of the 5 continuations have each of the preceeding continuations in its scope, and won't you therefore get really weird and complex cascading changes if you change something in one of the continuations around? Or, I suppose, it would do copy-on-write with the whole continuation? How the heck can the program reference everything without taking up gobs of memory? Finally, doesn't this take all kinds of complex program analysis to find out what changes and what doesn't in order to implement continuations efficiently?

Update: I asked for help over at Lambda the Ultimate and I've gotten at least one helpful response.

Update: Ian's written stuff on his weblog about this.

← Joe WilsonECMAScript for XML →

Comments XML gif

Ian Bicking (http://blog.ianbicking.org) wrote:

I don't entirely understand continuations myself, but I think you have to distinguish between the stack and the heap. The continuation saves the stack, but not the heap. The stack is a set of pointers into code, showing what operations is being executed in each frame. It also contains all the local bindings of each frame. These aren't the objects themselves, just the bindings, so if you have an object that is modified after you've creating a continuation, that object will still appear modified if you restart the continuation.

The heap, in constrast, is where all the actual data is held, where all the objects live. This is not copied, nor can you undo changes to the heap. This must be so, because in all useful programs it is actually impossible to undo changes, as not all changes are reflected in the heap (file writes, network communication, etc).

∴ Ian Bicking | 11-Jul-2004 9:52pm est | http://blog.ianbicking.org | #4973

Anton van Straaten wrote:

Ian's comment is spot on. The only thing I would add is that "stack" and "heap" are implementation concepts. In PL theory, the relevant concepts in this case are the lexical environment, and the "store". The lexical environment binds lexical variables to their values (possibly via "locations", depending on the model being used). The "store" is where actual values are stored. These roughly correspond to stack and heap respectively. Lexical closures, and continuations, close over (capture) the current lexical environment, not the store.

The reason it's important to conceptualize this independently of implementation concepts is that the standard stack-based implementations only implement a single, rigid model: that of functions which always return to their caller. If you're implementing systems that create and use continuations, you may not want to be limited by that model. There are many implementation strategies: you can stick to the traditional stack model and copy the relevant portion of the stack whenever a continuation or closure is captured; you can allocate all stack frames on the heap, eschewing the typical C-style stack completely (some ML implementations work like this); and there are many options in between, plus other models, like "Cheney on the MTA", used by Chicken Scheme, which treats the stack as the heap and just keeps pushing stack until it runs out of stack space, at which point it starts a new stack and garbage collects the old one.

So, it's helpful to think about the concepts independently of specific implementation strategies.

∴ Anton van Straaten | 12-Jul-2004 12:01am est | #4974

Keith Gaughan (http://talideon.com/) wrote:

What really cleared continuations up for me is:
http://www.ps.uni-sb.de/~duchier/python/continuations.html

∴ Keith Gaughan | 12-Jul-2004 9:21am est | http://talideon.com/ | #4984

sigfpe (http://www.sigfpe.com) wrote:

At least one implementation, in C, of a functional language, implements continuations by literally copying the C-stack to the heap. In effect it takes a snapshot of the state of the interpreter. Just for the hell of it I implemented the snapshot idea on its own here where I use it to implement something like coroutines in C. I once used those routines to write a Mathematica style algebraic expression pattern matcher with backtracking in C. If asked to implement something like that today in C/C++ I'd probably write code in continuation passing style rather than do a hack like that - but it was kinda fun at the time.

∴ sigfpe | 17-Dec-2004 11:58am est | http://www.sigfpe.com | #6652

Krishna (http://vkk.blogspot.com) wrote:

sigfpe,

I'm really interested as to how would you do the backtracking example (that you did using co-routines) using CPS in C/C++ ?

Although I can conceptually understand CPS, I have'nt seen any code in C/C++ . Can you provide an example ?

cheers,
-Krishna

∴ Krishna | 12-Feb-2005 1:17pm est | http://vkk.blogspot.com | #6998

Feel free to post a comment below. Please see my comment policy.

Formatting Rules (No HTML):

  • **bold**, *italic*, _underlined_, --strikeout--
  • "text"="url" creates a link, and URLs are auto-highlighted
  • Blockquote: Like e-mail, begin paragraph with > (greater-than sign)
  • Lists: begin paragraph with *,-, or + (unordered), or # (ordered)
  • Code block: ?!code:language=perl|php|sql|javascript|etc.{\n}...{\n}?!/code

:
(will be your IP address if blank)
: (optional)
(Will not be shown on site)

: (optional)
:

July 2008
SunMonTueWedThuFriSat
 12345
6789101112
13141516171819
20212223242526
2728293031 



RSS feed RSS feed for Keith's Weblog
Atom feed Atom feed for Keith's Weblog
Weblog archive
Recent comments
  on 2 posts

Recent comments XML

Spider solitaire

To answer an earlier question, I am​almost certain every game can be​beat. ...

Jared: Jul 16, 2:20pm

I hate Norton Antivirus

I HATE NORTON ANTIVIRUS IT SUCKS I​GOT AVG IT ROX! AGES TO DELETE​NORTON AN...

wade: Jul 15, 1:44am

Generated in about 0.142s.

(Used 8 db queries)

mobile phone