Copyright (C) 2000-2012 |
GNU Info (librep.info)ContinuationsContinuations ============= Whenever a function is called, there is a control path waiting to receive the result of the function, e.g. often the form following the function invocation. This waiting control path is called the "continuation" of the function, since control will continue down this path when the called function exits. These continuations are usually not paid much thought, but in some cases it may be useful to be able to directly manipulate the continuation of a function. For this purpose rep provides the `call-with-current-continuation' function (often shortened to `call/cc') that is standard in the Scheme dialect of Lisp. - Function: call/cc function FUNCTION is a function with a single parameter; it will be immediately invoked with this parameter bound to an object representing the current continuation (i.e. the control path that would be taken after FUNCTION exits). The continuation object passed to FUNCTION is itself a function accepting a single argument, when called it transfers control to the continuation of FUNCTION, as if FUNCTION had returned the argument applied to the continuation object. - Function: call-with-current-continuation function This is an alias for `call/cc'. In its simplest form, `call/cc' can mimic the `catch' and `throw' procedures (Note: Catch and Throw), for example: (defun foo (bar) (call/cc (lambda (esc) (when (null bar) ;; throws out of the call/cc (esc nil)) ;; do something with bar ... this is roughly equivalent to: (defun foo (bar) (catch 'tag (when (null bar) (throw 'tag nil)) ;; do something with bar ... This is only half the story--the most powerful feature of `call/cc' is that since continuations have dynamic extent (that is, no object is freed until no references to it exist) it is possible to return control to scopes that have already exited. For example, consider the following fragment of a lisp interaction: (prog1 (call/cc (lambda (esc) (setq cont esc))) (message "foo!")) -| foo! => #<closure> cont => #<closure> (cont 10) -| foo! => 10 The continuation of the `prog1' form is saved into the variable `cont'. When subsequently called with a single argument, it has exactly the same effect as the first time that the second form in the `prog1' construct was evaluated. Implementation Notes -------------------- `call/cc' works by making a copy of the process' entire call stack. For this reason, it is likely to be less efficient than using the control structures described in the previous parts of this section. Of course, it is much more powerful than the other constructs, so this often outweighs the slight inefficiency. Also note that currently no attempt is made to save or restore the dynamic state of the Lisp system, apart from variable bindings (both lexical and special). This means that any `unwind-protect', `condition-case' or `catch' forms that are active when invoking a continuation are all ignored. Another restriction is that invoking a continuation may not cause control to pass across a dynamic root (Note: Threads). automatically generated by info2www version 1.2.2.9 |