I need to work with continuations. I read the documentation about it and is very well written. Only the documentation about the racket/control library is a bit cryptic. I needed to ask the AI for help and I think I’ve spotted a bug about the difference between the shift and control operators.
The difference between shift and control is that shift adds a reset automatically:
;control
(prompt val) => val
(prompt E[(control k expr)]) => (prompt ((lambda (k) expr)
(lambda (v) E[v])))
;reset
(reset val) => val
(reset E[(shift k expr)]) => (reset ((lambda (k) expr)
(lambda (v) (reset E[v]))))
It's not a bug. If I had to guess, I think your mistake is forgetting that k1 is "just" a function, and the arguments to a function are evaluated before the function is called. So yes, k1 contains its own reset wrapper, but it doesn't affect the evaluation of the second shift.
Here is how the first example reduces, roughly:
(reset (+ 1 (shift k1
(k1 (+ 10 (shift k2 100))))))
;; Reduce the shift (k1).
;; E = (+ 1 [ ])
;; expr = (k1 (+ 10 (shift k2 100)))
(reset (let ([k1 (lambda (v1) (reset (+ 1 v1)))])
(k1 (+ 10 (shift k2 100)))))
;; Reduce the shift (k2). (The body of the let is a function call,
;; and we must evaluate the argument before calling the function.)
;; E = (let ([k1 ___]) (k1 (+ 10 [ ])))
;; expr = 100
(reset (let ([k2 (lambda (v2)
(reset (let ([k1 (lambda (v1) (reset (+ 1 v1)))])
(k1 (+ 10 v2)))))])
100))
;; Delete unused let bindings.
(reset 100)
;; Reduce the reset.
100
And here is how to the second example reduces:
(reset (+ 1 (shift k1
(k1 (reset (+ 10 (shift k2 100)))))))
;; Reduce the shift (k1).
;; E = (+ 1 [ ])
;; expr = (k1 (reset (+ 10 (shift k2 100))))
(reset (let ([k1 (lambda (v1) (reset (+ 1 v1)))])
(k1 (reset (+ 10 (shift k2 100))))))
;; Reduce the shift (k2). (The body of the let is a function call,
;; so we must evaluate the argument before calling the function.)
;; E = (+ 10 [ ])
;; expr = 100
;; within (reset (let ([k1 ___]) (k1 [ ])))
(reset (let ([k1 (lambda (v1) (reset (+ 1 v1)))])
(k1 (reset (let ([k2 (lambda (v2) (reset (+ 10 v2)))])
100)))))
;; Delete the unused let-binding of k2.
(reset (let ([k1 (lambda (v1) (reset (+ 1 v1)))])
(k1 (reset 100))))
;; Reduce the reset.
(reset (let ([k1 (lambda (v1) (reset (+ 1 v1)))])
(k1 100)))
;; Apply k1.
(reset (reset (+ 1 100)))
;; Apply +.
(reset (reset 101))
;; Reduce the reset.
(reset 101)
;; Reduce the reset.
101
To make the intermediate steps easier to read, I've written the result of a shift reduction using let and kept the let around instead of doing substitution eagerly. I hope it's clear.