I am reading The scheme programming language and seeing this example in continuation section:
(((call/cc (lambda (k) k)) (lambda (x) x)) "HEY!") => "HEY!"
I cannot figure out why this expression evaluating to "HEY!"
According to the CSE 341 lecture notes:
(call/cc expr) does the following:
- Captures the current continuation.
- Constructs a function
Cthat takes one argument, and applies the current continuation with that argument value. - Passes this function as an argument to
expr--- i.e., it invokes(expr C). - Returns the result of evaluating
(expr C), unlessexprcallsC, in which case the value that is passed toCis returned.
So, in this example (((call/cc (lambda (k) k)) (lambda (x) x)) "HEY!") => "HEY!"
the current continuation of
call/ccis(lambda (v) ((v (lambda (x) x)) "HEY!")the constructed function
Cis(lambda (y) ((lambda (v) ((v (lambda (x) x)) "HEY!")) y))invokes
((lambda (x) x) C)returns the result of evaluating
((lambda (x) x) C), which isCitself
Therefore, (call/cc (lambda (k) k)) evaluates to C. The whole expression will be:
(((lambda (y)
((lambda (v)
((v (lambda (x) x)) "HEY!")) y)) (lambda (x) x)) "HEY!")
i.e. ((C (lambda (x) x)) "HEY!"), which is ("HEY!" "HEY!").
This will result in an exception: Wrong type to apply: "HEY!", meaning applying a non-function value "HEY!".
Where am I wrong?
I'll attempt to break it down.
Starting with
the result of evaluating
((call/cc (lambda (k) k)) (lambda (x) x))needs to be a function, and it's called with the argument"HEY!".calls an anonymous function and passes it a continuation, a special function that when called, will return its argument to where
call/ccreturns to. The anonymous function just returns that continuation without calling it. Call that continuationkont, and substitute it for the wholecall/ccexpression:That continuation is now called, with an anonymous function that takes one argument and returns it as its argument. That function is thus the result of evaluating the continuation. So basically
((call/cc (lambda (k) k)) (lambda (x) x))is equivalent to(lambda (x) x). Which is then called with the argument"HEY!", which it then returns.