Continuations and call/cc

Continuations can implement exceptions, generators, coroutines, backtracking (amb), cooperative threads, and web frameworks that keep state across requests (Racket's web server).

Delimited continuations (shift/reset, Racket's call-with-composable-continuation, control/prompt) capture only part of the stack and are easier to reason about.

;; A continuation represents "the rest of the computation" at some point
(+ 1 (call/cc (lambda (k) (k 41))))      ; 42: k returns 41 to the waiting (+ 1 _)

;; Early exit from a loop
(define (find-first pred lst)
  (call/cc
    (lambda (return)
      (for-each (lambda (x) (when (pred x) (return x))) lst)
      #f)))
(find-first negative? '(1 2 -3 4 -5))    ; -3

;; Continuations can be saved and re-entered later (re-entry at the top level
;; behaves differently across implementations, so the generator below keeps it local)

;; Generators with continuations
(define (make-generator lst)
  (define return #f)                     ; where to deliver the next value (updated on every call)
  (define resume                         ; where to continue the traversal
    (lambda (ignored)
      (for-each (lambda (x)
                  (call/cc (lambda (k)
                             (set! resume k)
                             (return x))))
                lst)
      (return 'done)))
  (lambda ()
    (call/cc (lambda (r)
               (set! return r)
               (resume #f)))))
(define g (make-generator '(a b c)))
(g) (g) (g) (g)                          ; a b c done
#lang racket
(require racket/control)
(+ 1 (reset (+ 10 (shift k (k (k 100))))))   ; 121: k = (λ (v) (+ 10 v)), applied twice → 120, plus 1