Closures get a lot of the press; so here's something that many everyday programmers don't know about.
First off, definitions:
- A Continuation is the computational state of a program (i.e. - function stack, not heap) saved into a data structure for later user.
- A higher order function is a function that takes another function as a parameter; or it is a function that returns a function as its output; or it is both.
- A non-local return is a way to immediately exit a function and transfer control to some point in function stack; similar to goto, but not quite.
call-with-current-continuation is a Scheme higher order function that saves the current computational state, and then executes an abortable procedure (a higher order function passed in as the call-with-current-continuation's sole parameter); the called abortable procedure, which has only one parameter, is given an escape procedure; calling the escape procedure from within the abortable procedure will execute a non-local return back to its respective call-with-current-continuation; the return value of the call-with-current-continuation is either the natural return value of the abortable procedure or a single value passed to the escape procedure; and call-with-current-continuation is also known by its shorter alias: call/cc.
Example:
; Define some procedure I want to escape from.
(define my_abortable_procedure
(lambda (escape_procedure)
; Do stuff
(+ 1 1)
;nonlocal return
(escape_procedure 'SOMEVALUE)
(display 'NEVERREACHED_WHEN_ESCAPE_IS_CALLED)))
(display (call/cc my_abortable_procedure))
; displays: SOMEVALUE
; The return value of call/cc is the value either returned by my_abortable_procedure or
; the value passed to escape_procedure
Here's an example I found showing how one can jump back into a function call instead of escaping it.
(define return #f)
(+ 1 (call/cc
(lambda (cont)
(set! return cont)
1)))
; The above returns 2
(return 22)
; The above returns 23
So what's it all good for? Well, examples of use include Exceptions (e.g. - catch, throw, raise, and rescue), Co-routines, Backtracking, and Cooperative Multitasking.
"But I don't use Scheme (or Lisp)."
[UPDATE:12JUNE2007] - I just watched the The 90 Minute Scheme to C compiler talk given by Marc Feeley in 2004; part one takes an incredible 10 minute tangent into talking about call/cc (while talking about continuations in general). Definitely watch it for a great explanation.