07 September 2007

Quick Note on Continuations to comp.lang.scheme

I just posted a quick note on continuations to c.l.s. I'm afraid it's pretty basic, and doesn't really do the topic justice, but maybe the original poster will find it helpful. I'm noting it here because no ever seems to explain continuations the way I did in my note (at least, I haven't seen any explanations like this), which uses "return points" to illustrate what continuations do. I don't fully understand continuations (in particular, I have a lot of trouble with the delimited continuations that PLT Scheme has recently acquired), but thinking of them the way I talk about in the c.l.s. post is the way I manage to muddle through using them. How do others think about call/cc? (i.e. what images are going through your head while you figure out how to do what you want with call/cc in code, not how do you formalize call/cc, or how you explain it to someone else, or ....)

3 comments:

Unknown said...

The way I like to think of call/cc, is to picture how it works compared to a normal stack based language. Conceptually, call/cc captures the entire current program stack and creates a "magic function" that, when called, will abort the current stack and restore the original one. The function that you pass to call/cc then gets called with this "magic function" as a parameter.

The interesting thing is that calling this "magic function" is kind of like going back in time in your program's execution, because the program stack is restored. And if you save the "magic function" somewhere (using set!) you can jump back to the same state multiple times. However, it's a little different from going back in time because you can still see side effects that were produced by changes in the heap (e.g. set!).

Just to tie back to standard terminology, the "magic function" I mention above is actually the program's current continuation captured at the time when call/cc was called.

Of course, there's no reason call/cc needs to be implemented by copying the entire program stack. That's just a way of thinking about how it works. :)

Ian Bicking said...

A while ago I tried to explain continuations in a similar fashion -- more mechanical than theoretical. It might be helpful to readers here too: http://blog.ianbicking.org/continuations-a-concrete-approach.html

Jeremy said...

A few years back I did some talks on Scheme continuations. In the slides, I tried to describe continuations in terms of closures. In particular, if you think about what is stored so that you can return from a function, it's a pointer to the return-code, and a pointer to the return environment. Code+environment is pretty much a closure. You usually return one result, so it's typically a closure expecting one argument. All call/cc does is gives you that closure to use in more exciting ways than it normally gets used.