(import (rnrs)) ;R6RS (import (rnrs base)) ;R6RS (import (scheme r5rs)) ;R7RS (import (scheme base)) ;R7RS
(call-with-current-continuation proc) (call/cc proc)
The escape procedure is a procedure that, if it is later called, will abandon whatever continuation is in effect at that later time and will instead reinstate the continuation that was in effect when the escape procedure was created.
Escape procedures in many other languages can only be called once. It is also a common limitation that escape procedures can only be called "upwards", meaning that it's impossible to re-enter a context once it has been returned from. This allows you to implement simpler things like exception handling, but it is very limited compared to what call/cc provides.
Simply speaking, this is any number of arguments if the call happened in a begin(7scm) and a single argument if it happened in the evaluation of an argument to a procedure call. If the continuation was created by call-with-values(3scm) then it accepts the same number of arguments as the consumer procedure.
Note however that this explanation is overly concrete and if that was the specification then many optimizations performed by compilers would be impossible. Because call/cc is specified on a language-level, not a concrete machine level, many optimizations can be performed in intermediate steps of the compiler. As an example, obvious uses of call/cc to return from a function can be optimized into function returns. No copying of the stack is needed for these simple case.
A full discussion on the various methods for implementing continuations is out of scope for this manual page, but here are some pointers for the interested reader: continuation-passing style, Cheney on the M.T.A. (CHICKEN) and segmented stacks (Chez Scheme).
(call/cc (lambda (return) (return 47) (display "This does not run0))) => 47 (call-with-current-continuation (lambda (exit) (for-each (lambda (x) (when (negative? x) (exit x))) '(54 0 37 -3 245 19)) #t)) => -3 (define list-length (lambda (obj) (call-with-current-continuation (lambda (return) (letrec ((r (lambda (obj) (cond ((null? obj) 0) ((pair? obj) (+ (r (cdr obj)) 1)) (else (return #f)))))) (r obj)))))) (list-length '(1 2 3 4)) => 4 (list-length '(a b . c)) => #f (call-with-current-continuation procedure?) => #t
The classic use of call-with-current-continuation is for structured, non-local exits from loops or procedure bodies, but in fact call-with-current-continuation is extremely useful for implementing a wide variety of advanced control structures.
Whenever a Scheme expression is evaluated there is a continuation wanting the result of the expression. The continuation represents an entire (default) future for the computation. If the expression is evaluated at top level, for example, then the continuation will take the result, print it on the screen, prompt for the next input, evaluate it, and so on forever. Most of the time the continuation includes actions specified by user code, as in a continuation that will take the result, multiply it by the value stored in a local variable, add seven, and give the answer to the top level continuation to be printed. Normally these ubiquitous continuations are hidden behind the scenes and programmers don’t think much about them. On rare occasions, however, when programmers need to do something fancy, then they may need to deal with continuations explicitly, call-with-current-continuation allows Scheme programmers to do that by creating a procedure that acts just like the current continuation.
Most serious programming languages incorporate one or more special purpose escape constructs with names like exit, return, or even goto. In 1965, however, Peter Landin invented a general purpose escape operator called the J-operator. John Reynolds described a simpler but equally powerful construct in 1972. The catch special form described by Sussman and Steele in the 1975 report on Scheme is exactly the same as Reynolds's construct, though its name came from a less general construct in MacLisp. The fact that the full power of Scheme's catch could be obtained using a procedure rather than a special form was noticed in 1982 by the implementors of Scheme 311, and the name call-with-current-continuation was coined later that year. Although the name is descriptive, some people feel it is too long and have taken to calling the procedure call/cc.