Call-with-current-continuation
From Wikipedia, the free encyclopedia
Call-with-current-continuation, commonly abbreviated call/cc, is a control function in Scheme and several other programming languages. Taking a function f as its only argument, it passes it the current continuation (i.e. the execution state of the program) as an argument. This allows f to restore the continuation at any time, thus passing control to the next statement after the call to call/cc.
The continuation can be called like an ordinary function, but it will not return to its caller; instead, control flow continues from the point just after the call to call/cc that produced the continuation (the code that follows the continuation call is simply ignored).
Call/cc can be used to simulate a return keyword, which is missing from Scheme:
(define (f return) (return 2) 3) (display (call-with-current-continuation f))
Calling f with a regular function argument first applies this function to the value 2, then returns 3. However, when f is passed to call/cc (as in the last line of the example), applying the parameter (the continuation) to 2 forces execution of the program to jump to the point where call/cc was called, and causes call/cc to return the value 2. This is then printed by the display function.
The power of call/cc lies in the ability for the continuation to be called more than once, and even from outside the lexical context of the call/cc construction: there are no rules stating that the continuation has to "stay inside" call/cc. The programmer can "return" as many times as he likes.
In the example below, an imperative cycle is created by repeatedly resuming the saved continuation next:
(let ((next #f)
(i 0))
(display (call-with-current-continuation
(lambda (f)
(set! next f)
"-")))
(newline)
(set! i (+ i 1))
(if (<= i 5)
(next i)))
Call/cc has been used for several practical purposes, such as implementing amb, an operator which emulates Prolog-style backtracking. Call/cc has also been used to create an exception system in Scheme, as R5RS does not specify one built in. Another use of call/cc is the creation of coroutines, employing call/cc to jump back and forth between them. Similarly, call/cc can help implement Python-like generators.
Call/cc has been criticized, especially by Lisp users, as being an unnecessarily complicated and difficult-to-implement means for doing the above things. Critics hold that each one of those tasks can and should be implemented without call/cc, and that doing so will make things faster and more efficient. Indeed, in many implementations of Scheme, call/cc is rather slow. To have a speedy call/cc, the operator often needs to be central in design by, for example, using continuation passing style in an intermediate stage of the compiler.
- A short introduction to
call-with-current-continuation - Definition of
call-with-current-continuationin the Scheme spec
This article was originally based on material from the Free On-line Dictionary of Computing, which is licensed under the GFDL.