Here's my attempt (warning: I am an inexperienced schemer). Let get-cc
be the function returning the current continuation.
(define (get-cc)
(call-with-current-continuation (lambda (k) k)))
Then, we can define:
(define (callCC f)
(let ((w (get-cc)))
(if (pair? w)
(car w)
(f (lambda (x) (w (cons x '())))))))
The first time this function is called, w
is bound to the current continuation. So, (pair? w)
is false, and we call f
with continuation (lambda (x) (w (cons x '()))
.
When w
is called though f
(with argument (cons x '())
), then the body of the let
is entered again, where w
is now bound to (cons x '())
.
Now, (pair? w)
is true, and we can return (car w)
which is x
.
The pair wrapper is used so as to distinguish what is "the continuation for f
" from "the result from f
", so to speak.
A quick test shows this to be working, but I'm not completely confident of its correctness.
You probably noticed that w
is bound to values of different types. That is why I resorted to an untyped language like Scheme instead of Haskell.