Hello!
Here it is a strange function in Scheme:
(define f (call/cc (lambda (x) x) ) )
(((f 'f) f) 1 )
When f is called in the command line, the result displayed is f . What is the explanation of this mechanism ?..
Thanks!
Hello!
Here it is a strange function in Scheme:
(define f (call/cc (lambda (x) x) ) )
(((f 'f) f) 1 )
When f is called in the command line, the result displayed is f . What is the explanation of this mechanism ?..
Thanks!
You've just stumbled upon 'continuations', possibly the hardest thing of Scheme to understand.
call/cc
is an abbreviation for call-with-current-continuation
, what the procedure does is it takes a single argument function as its own argument, and calls it with the current 'continuation'.
So what's a continuation? That's infamously hard to explain and you should probably google it to get a better explanation than mine. But a continuation is simply a function of one argument, whose body represents a certain 'continuation' of a value.
Like, when we have (+ 2 (* 2 exp))
with exp being a random expression, if we evaluate that expression there is a 'continuation' waiting for that result, a place where evaluation continues, if it evaluates to 3 for instance, it inserts that value into the expression (* 2 3)
and goes on from there with the next 'continuation', or the place where evaluation continues, which is (+ 2 ...)
.
In almost all contexts of programming languages, the place where computation continues with the value is the same place as it started, though the return
statement in many languages is a key counterexample, the continuation is at a totally different place than the return statement itself.
In Scheme, you have direct control over your continuations, you can 'capture' them like done there. What f
does is nothing more than evaluate to the current continuation, after all, when (lambda (x) x)
is called with the current continuation, it just evaluates to it, so the entire function body does. As I said, continuations are functions themselves whose body can just be seen as the continuation they are to capture, which was famously shown by the designers of Scheme, that continuations are simply just lambda abstractions.
So in the code f first evaluates to the continuation it was called in. Then this continuation as a function is applied to 'f
(a symbol). This means that that symbol is brought back to that continuation, where it is evaluated again as a symbol, to reveal the function it is bound to, which again is called with a symbol as its argument, which is finally displayed.
Kind of mind boggling, if you've seen the film 'primer', maybe this explains it: