Call-with-current-continuation
   HOME

TheInfoList



OR:

In the
Scheme A scheme is a systematic plan for the implementation of a certain idea. Scheme or schemer may refer to: Arts and entertainment * ''The Scheme'' (TV series), a BBC Scotland documentary series * The Scheme (band), an English pop band * ''The Schem ...
computer programming Computer programming is the process of performing a particular computation (or more generally, accomplishing a specific computing result), usually by designing and building an executable computer program. Programming involves tasks such as ana ...
language, the procedure call-with-current-continuation, abbreviated call/cc, is used as a
control flow In computer science, control flow (or flow of control) is the order in which individual statements, instructions or function calls of an imperative program are executed or evaluated. The emphasis on explicit control flow distinguishes an ''imper ...
operator. It has been adopted by several other programming languages. Taking a function f as its only argument, (call/cc f) within an expression is applied to the current
continuation In computer science, a continuation is an abstract representation of the control state of a computer program. A continuation implements ( reifies) the program control state, i.e. the continuation is a data structure that represents the computati ...
of the expression. For example ((call/cc f) e2) is equivalent to applying f to the current continuation of the expression. The current continuation is given by replacing (call/cc f) by a variable c bound by a lambda abstraction, so the current continuation is (lambda (c) (c e2)). Applying the function f to it gives the final result (f (lambda (c) (c e2))). As a complementary example, in an expression (e1 (call/cc f)), the continuation for the sub-expression (call/cc f) is (lambda (c) (e1 c)), so the whole expression is equivalent to (f (lambda (c) (e1 c))). In other words it takes a "snapshot" of the current control context or control state of the program as an object and applies f to it. The continuation object is a
first-class value In Programming language#Design and implementation, programming language design, a first-class citizen (also type, object, entity, or value) in a given programming language is an entity which supports all the operations generally available to other ...
and is represented as a function, with
function application In mathematics, function application is the act of applying a function to an argument from its domain so as to obtain the corresponding value from its range. In this sense, function application can be thought of as the opposite of function abst ...
as its only operation. When a continuation object is applied to an argument, the existing continuation is eliminated and the applied continuation is restored in its place, so that the program flow will continue at the point at which the continuation was captured and ''the argument of the continuation'' then becomes the "return value" of the call/cc invocation. Continuations created with call/cc may be called more than once, and even from outside the dynamic extent of the call/cc application. In computer science, making this type of implicit program state visible as an object is termed '' reification''. (
Scheme A scheme is a systematic plan for the implementation of a certain idea. Scheme or schemer may refer to: Arts and entertainment * ''The Scheme'' (TV series), a BBC Scotland documentary series * The Scheme (band), an English pop band * ''The Schem ...
does not syntactically distinguish between applying continuations or functions.) With call/cc a variety of complex control operators can be implemented from other languages via a few lines of code, e.g., McCarthy's amb operator for nondeterministic choice,
Prolog Prolog is a logic programming language associated with artificial intelligence and computational linguistics. Prolog has its roots in first-order logic, a formal logic, and unlike many other programming languages, Prolog is intended primarily ...
-style
backtracking Backtracking is a class of algorithms for finding solutions to some computational problems, notably constraint satisfaction problems, that incrementally builds candidates to the solutions, and abandons a candidate ("backtracks") as soon as it de ...
,
Simula Simula is the name of two simulation programming languages, Simula I and Simula 67, developed in the 1960s at the Norwegian Computing Center in Oslo, by Ole-Johan Dahl and Kristen Nygaard. Syntactically, it is an approximate superset of ALGOL 6 ...
67-style
coroutine Coroutines are computer program components that generalize subroutines for non-preemptive multitasking, by allowing execution to be suspended and resumed. Coroutines are well-suited for implementing familiar program components such as cooperative ...
s and generalizations thereof,
Icon An icon () is a religious work of art, most commonly a painting, in the cultures of the Eastern Orthodox, Oriental Orthodox, and Catholic churches. They are not simply artworks; "an icon is a sacred image used in religious devotion". The most ...
-style
generator Generator may refer to: * Signal generator, electronic devices that generate repeating or non-repeating electronic signals * Electric generator, a device that converts mechanical energy to electrical energy. * Generator (circuit theory), an eleme ...
s, or
engine An engine or motor is a machine designed to convert one or more forms of energy into mechanical energy. Available energy sources include potential energy (e.g. energy of the Earth's gravitational field as exploited in hydroelectric power gen ...
s and threads or even the obscure
COMEFROM In computer programming, COMEFROM (or COME FROM) is an obscure control flow structure used in some programming languages, originally as a joke. COMEFROM is the inverse of GOTO in that it can take the execution state from any arbitrary point in code ...
.


Examples

As shown by the next example, call/cc can be used to emulate the function of the
return statement In computer programming, a return statement causes execution to leave the current subroutine and resume at the point in the code immediately after the instruction which called the subroutine, known as its return address. The return address is sav ...
known from C-style languages, which is missing from
Scheme A scheme is a systematic plan for the implementation of a certain idea. Scheme or schemer may refer to: Arts and entertainment * ''The Scheme'' (TV series), a BBC Scotland documentary series * The Scheme (band), an English pop band * ''The Schem ...
: (define (f return) (return 2) 3) (f (lambda (x) x)) => 3 (call-with-current-continuation f) => 2 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. In the next example, call/cc is used twice: once to generate a "return" continuation as in the first example and once to suspend an iteration through a list of items: ;; ISTOF X-> ( -> X u 'you-fell-off-the-end) (define (generate-one-element-at-a-time lst) ;; Both internal functions are closures over lst ;; Internal variable/Function which passes the current element in a list ;; to its return argument (which is a continuation), or passes an end-of-list marker ;; if no more elements are left. On each step the function name is ;; rebound to a continuation which points back into the function body, ;; while return is rebound to whatever continuation the caller specifies. (define (control-state return) (for-each (lambda (element) (set! return (call-with-current-continuation (lambda (resume-here) ;; Grab the current continuation (set! control-state resume-here) (return element))))) ;; (return element) evaluates to next return lst) (return 'you-fell-off-the-end)) ;; (-> X u 'you-fell-off-the-end) ;; This is the actual generator, producing one item from a-list at a time. (define (generator) (call-with-current-continuation control-state)) ;; Return the generator generator) (define generate-digit (generate-one-element-at-a-time '(0 1 2))) (generate-digit) ;; 0 (generate-digit) ;; 1 (generate-digit) ;; 2 (generate-digit) ;; you-fell-off-the-end Every time the loop is about to process another item from the list, the function grabs the current continuation, and assigns it to the variable 'control-state'. This variable initially is the closure that iterates through all elements of the list. As the computation progresses, it becomes a closure that iterates through a suffix of the given list. While the use of "call/cc" is unnecessary for a linear collection, such as ISTOF X/code>, the code generalizes to ''any'' collection that can be traversed. Call-with-current-continuation can also express other sophisticated primitives. For example, the next sample performs cooperative multitasking using continuations: ;; Cooperative multitasking using call-with-current-continuation ;; in 25 lines of scheme ;; The list of threads waiting to run. This is a list of one ;; argument non-returning functions (continuations, mostly) ;; A continuation is a non-returning function, just like (exit), ;; in that it never gives up control to whatever called it. (define ready-list '()) ;; A non-returning function. If there is any other thread ;; waiting to be run, it causes the next thread to run if there ;; is any left to run, otherwise it calls the original exit ;; which exits the whole environment. (define exit ;; The original exit which we override. (let ((exit exit)) ;; The overriding function. (lambda () (if (not (null? ready-list)) ;; There is another thread waiting to be run. ;; So we run it. (let ((cont (car ready-list))) (set! ready-list (cdr ready-list)) ;; Since the ready-list is only non-returning ;; functions, this will not return. (cont #f)) ;; Nothing left to run. ;; The original (exit) is a non returning function, ;; so this is a non-returning function. (exit))))) ;; Takes a one argument function with a given ;; argument and forks it off. The forked function's new ;; thread will exit if/when the function ever exits. (define (fork fn arg) (set! ready-list (append ready-list ;; This function added to the ;; ready-list is non-returning, ;; since exit is non returning. (list (lambda (x) (fn arg) (exit)))))) ;; Gives up control for the next thread waiting to be run. ;; Although it will eventually return, it gives up control ;; and will only regain it when the continuation is called. (define (yield) (call-with-current-continuation ;; Capture the continuation representing THIS call to yield (lambda (cont) ;; Stick it on the ready list (set! ready-list (append ready-list (list cont))) ;; Get the next thread, and start it running. (let ((cont (car ready-list))) (set! ready-list (cdr ready-list)) ;; Run it. (cont #f))))) In 1999, David Madore (inventor of the
Unlambda Unlambda is a minimal, "nearly Purely functional language, pure" functional programming language invented by David Madore. It is based on combinatory logic, an expression system without the Lambda calculus, lambda operator or free variables. It r ...
programming language) accidentally discovered a 12-character Unlambda term, making use of call/cc, that printed all natural numbers sequentially in unary representation: ``r`ci`.*`ci. This program and the apparent mystery surrounding its effect have attracted some attention, and are commonly known as the ''yin-yang puzzle''. A Scheme translation, provided by Madore, is as follows: (let* ((yin ((lambda (cc) (display #\@) cc) (call-with-current-continuation (lambda (c) c)))) (yang ((lambda (cc) (display #\*) cc) (call-with-current-continuation (lambda (c) c))))) (yin yang))


Criticism

Oleg Kiselyov, author of a delimited continuation implementation for
OCaml OCaml ( , formerly Objective Caml) is a general-purpose programming language, general-purpose, multi-paradigm programming language which extends the Caml dialect of ML (programming language), ML with object-oriented programming, object-oriented ...
, and designer of an
application programming interface An application programming interface (API) is a way for two or more computer programs to communicate with each other. It is a type of software interface, offering a service to other pieces of software. A document or standard that describes how t ...
(API) for delimited stack manipulation to implement control operators, advocates the use of delimited continuations instead of the full-stack continuations that call/cc manipulates: "Offering call/cc as a core control feature in terms of which all other control facilities should be implemented turns out a bad idea. Performance, memory and resource leaks, ease of implementation, ease of use, ease of reasoning all argue against call/cc."


Relation to non-constructive logic

The
Curry–Howard correspondence In programming language theory and proof theory, the Curry–Howard correspondence (also known as the Curry–Howard isomorphism or equivalence, or the proofs-as-programs and propositions- or formulae-as-types interpretation) is the direct relati ...
between proofs and programs relates ''call/cc'' to
Peirce's law In logic, Peirce's law is named after the philosopher and logician Charles Sanders Peirce. It was taken as an axiom in his first axiomatisation of propositional logic. It can be thought of as the law of excluded middle written in a form that i ...
, which extends
intuitionistic logic Intuitionistic logic, sometimes more generally called constructive logic, refers to systems of symbolic logic that differ from the systems used for classical logic by more closely mirroring the notion of constructive proof. In particular, systems ...
to non-constructive,
classical logic Classical logic (or standard logic or Frege-Russell logic) is the intensively studied and most widely used class of deductive logic. Classical logic has had much influence on analytic philosophy. Characteristics Each logical system in this class ...
: ((α → β) → α) → α. Here, ((α → β) → α) is the type of the function ''f'', which can either return a value of type α directly or apply an argument to the continuation of type (α → β). Since the existing context is deleted when the continuation is applied, the type β is never used and may be taken to be ⊥, the empty type. The principle of
double negation elimination In propositional logic, double negation is the theorem that states that "If a statement is true, then it is not the case that the statement is not true." This is expressed by saying that a proposition ''A'' is logically equivalent to ''not (not ...
((α → ⊥) → ⊥) → α is comparable to a variant of call-cc which expects its argument ''f'' to always evaluate the current continuation without normally returning a value. Embeddings of classical logic into intuitionistic logic are related to
continuation passing style In functional programming, continuation-passing style (CPS) is a style of programming in which control is passed explicitly in the form of a continuation. This is contrasted with direct style, which is the usual style of programming. Gerald Jay Suss ...
translation.


Languages implementing call/cc

*
Scheme A scheme is a systematic plan for the implementation of a certain idea. Scheme or schemer may refer to: Arts and entertainment * ''The Scheme'' (TV series), a BBC Scotland documentary series * The Scheme (band), an English pop band * ''The Schem ...
* Racket *
Standard ML Standard ML (SML) is a general-purpose, modular, functional programming language with compile-time type checking and type inference. It is popular among compiler writers and programming language researchers, as well as in the development of the ...
*
Haskell Haskell () is a general-purpose, statically-typed, purely functional programming language with type inference and lazy evaluation. Designed for teaching, research and industrial applications, Haskell has pioneered a number of programming lan ...
in the continuation Monad *
Ruby A ruby is a pinkish red to blood-red colored gemstone, a variety of the mineral corundum ( aluminium oxide). Ruby is one of the most popular traditional jewelry gems and is very durable. Other varieties of gem-quality corundum are called sa ...
*
Unlambda Unlambda is a minimal, "nearly Purely functional language, pure" functional programming language invented by David Madore. It is based on combinatory logic, an expression system without the Lambda calculus, lambda operator or free variables. It r ...
*
C++ C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
* R


See also

*
Goto GoTo (goto, GOTO, GO TO or other case combinations, depending on the programming language) is a statement found in many computer programming languages. It performs a one-way transfer of control to another line of code; in contrast a function ca ...
*
Continuation-passing style In functional programming, continuation-passing style (CPS) is a style of programming in which control is passed explicitly in the form of a continuation. This is contrasted with direct style, which is the usual style of programming. Gerald Jay Suss ...
*
Fiber (computer science) In computer science, a fiber is a particularly lightweight thread of execution. Like threads, fibers share address space. However, fibers use cooperative multitasking while threads use preemptive multitasking. Threads often depend on the kerne ...


References


External links


A short introduction to call-with-current-continuation
* ttps://groups.google.com/group/comp.lang.lisp/msg/4e1f782be5ba2841 Humorous explanation of call-with-current-continuation from Rob Warnock in Usenet's comp.lang.lispbr>Cooperative multitasking in Scheme using Call-CC
{{Lisp programming language Continuations Scheme (programming language) Subroutines