[ prog / sol / mona ]

prog


How to learn Scheme's continuations

1 2021-09-14 00:49

How do I learn Scheme's call-with-current-continuation (call/cc)? I want to know what it is, what it is used for, and how it can be implemented (e.g. added to a metacircular evaluator). Are there any resources for someone who has just finished reading SICP?

2 2021-09-14 06:54

It's like setjump

3 2021-09-14 07:10

Think of the Scheme program as a tree. Imagine that it is evaluated by replacing each node with its value, starting from the leafs. So if you have (/ (+ 1 2) 3), evaluating (+ 1 2) will give you (/ 3 3), etc. Now if you consider any node in the original tree, its continuation will be this replacement. For example, for (+ 1 2) the continuation will be (lambda (v) (/ v 3)), for the 3 it will be (lambda (v) (/ (+ 1 2) v)), and so on.

call/cc will work in this as a "shortcut". It gives you a continuation, something like a function, that also replaces the whole tree. Consider the following example:

(+ 1
   (call/cc
    (lambda (k)
      (+ 5 (k (+ 1 2))))))

First, we evaluate (+ 1 2):

(+ 1
   (call/cc
    (lambda (k)
      (+ 5 (k 3)))))

Now k, the continuation, is invoked, and instead of just replacing it with a value, we replace the whole tree with the value passed to it!

(+ 1 3)

You can see that it skipped the whole (+ 5 ...) thing.

Or something like this, I hope this gives you a general idea. I cheated and ignored a few things (evaluating 1==, ==+, etc., plus first we should evaluate (call/cc λ) to (λ k) and so on), but I am already late from work so I hope at least this will be of some help and it doesn't just confuse you further.

4 2021-09-15 00:28

>>3
Why would I want to use call/cc? I don't see why I would ever need something like that.

5 2021-09-15 06:40

>>4
You can use it to implement all kinds of fancy control structures: early exit, exceptions, backtracking, engines, co-routines, and so on.

6 2021-09-18 23:55

http://wiki.c2.com/?CallWithCurrentContinuation

If you're a C programmer, you might find this explanation easier: in C, you can take a pointer to a function. In C, you also have a return statement. Suppose the return statement were a function (which never returned, of course). It would take a parameter of the same type as the return type of the function it was returning from. Now suppose you could take its address. You could store that address in a variable or pass it as a parameter, and allow functions to return on your behalf. That's what call/cc allows you to do. You can use it as a replacement for throw and catch, or you can set up coroutines with it

7


VIP:

do not edit these