I'm familiar with using call/cc
to interpret CPS programs in a direct style:
(define (f return)
(return 2)
3)
(f (lambda (x) x))
=> 3
(call/cc f)
=> 2
I'm also familiar with how (call/cc call/cc)
behaves, with ((call/cc call/cc) x)
being equivalent to (x x)
:
((call/cc call/cc) display)
=> #<procedure #2 display>
The outer call/cc
calls the argument call/cc
with f
that represents a continuation
(★ display)
But what continuation does the inner call/cc
pass to f
, considering that it wasn't called at a source location and was called as "part of a higher-order function"/"a value"?
If it's treated as being evaluated at the source location, intuition tells me it'll reduce similarly to:
((¹call/cc ²call/cc) display)
(²call/cc ¹(★ display))
(²((¹call/cc ★) display) display)
((¹call/cc display) display)
(display ¹(★ display))
which does not match the behavior (display display)
.
Maybe you're being a bit misled by the Wikipedia page because it only explains continuations by examples, which are too limited to cover your question.
Every expression has a continuation representing everything that happens afterward. Conventionally we write
E[ expr ] c
to say "the meaning of expr with continuation c". Scheme implements a set of rules concerning such meanings. For example
E[ (+ A B) ] c = E[A] lambda (a) E[B] lambda (b) (c (+ a b))
The meaning of the Scheme addition of A and B is the meaning of A with a continuation that accepts that value and finds the meaning of B with a continuation that accepts that value, adds both values, and calls the continuation with the result as a parameter.
Okay. Now we're ready for the definition of call/cc:
E[ (call/cc F) ] c = E[ (F c) ] c
That is, the meaning of (call/cc f) with continuation c is the just the meaning of f applied to c with unchanged continuation. I think this answers your question: the continuation isn't altered by call/cc. It's just "exposed" as a parameter.
(This rule actually leaves stuff out for simplicity. Finding the meaning of F before it's called should be spelled out.)
So let's look at the case (call/cc call/cc):
E[ (call/cc call/cc) ] c = E[ (call/cc c) ] c = E[ (c c) ] c
That is, the meaning of (call/cc call/cc) is the continuation of this expression applied to itself.
For example, suppose we have ((call/cc call/cc) foo). The continuation here is (lambda (c) (c foo)) (as in the Wikipedia page). So the result will be:
((lambda (c) (c foo)) (lambda (c) (c foo))) => ((lambda (c) (c foo)) foo) => (foo foo)
So if foo is the identity, then so is the overall meaning of the expression.
I hope this is helpful.