20-CS-4003-001 | Organization of Programming Languages | Fall 2017 |
---|---|---|
Call-with-current-continuation examples |
Escaping from a deeply nested procedure call
(define call/cc call-with-current-continuation) (define proc (lambda () (let ((halt (call/cc (lambda (k) k)))) (if (procedure? halt) (letrec ((looper (lambda (n) (if (= n 1000) (halt n) (looper (+ n 1)))))) (looper 1)) halt)))) |
- | When (call/cc (lambda (k) ...) is invoked k becomes a place in the heap that can be returned to using (k <value>). But to make this happen, k must somehow be returned from the (call/cc ...) invocation. In this simple example, when proc is invoked with no arguments, it is returned just by itself and a reference to it is kept by halt. The letrec defines a procedure looper which increments an input number by 1 every time it recurses. When it reaches 100 (halt n) is invoked. But halt is the continuation that was "grabbed" in the let. So, control goes "back in time" to before the invocation of looper and this time returns the value of n (which is 1000) to halt. Since halt is now a number, the test (procedure? halt) is false causing looper to be bypassed and resulting in the value of 1000 returned by proc. |