Continuation-Passing Style
Tutorial Video
Text description (accessibility)
This video demonstrates the "Continuation-Passing Style" functional Rust example. Difficulty level: Advanced. Key concepts covered: Functional Programming. Continuation-passing style (CPS) transforms functions so that instead of returning a value, they pass the result to a "continuation" callback. Key difference from OCaml: 1. **Tail call optimization**: OCaml guarantees TCO for direct tail calls and can optimize CPS; Rust does not guarantee TCO — CPS in Rust still risks stack overflow without trampolining.
Tutorial
The Problem
Continuation-passing style (CPS) transforms functions so that instead of returning a value, they pass the result to a "continuation" callback. CPS makes control flow explicit — every function knows exactly what happens next. It is the basis for compilers (CPS intermediate representations in GHC, MLton), non-local exits, and cooperative scheduling. CPS transform eliminates the call stack: tail calls to continuations never grow the stack.
🎯 Learning Outcomes
callcc (call-with-current-continuation) enables non-local exits and backtrackingCode Example
#![allow(clippy::all)]
// Stub — awaiting conversion from OCaml source.Key Differences
callcc**: OCaml's effects provide first-class continuations; Rust lacks callcc — non-local exits use Result and ?, not continuations.callcc enables coroutines, backtracking, and non-local exits; Rust's CPS simulation provides only the direct sequencing benefit.OCaml Approach
OCaml naturally supports CPS:
let add_k a b k = k (a + b)
let factorial_k n k =
let rec go n acc k = if n = 0 then k acc else go (n-1) (n*acc) k in
go n 1 k
OCaml has a callcc library via setjmp/longjmp (unsafe) or via effects (OCaml 5). The delimcc library provides delimited continuations. CPS is a common intermediate representation in OCaml compilers.
Full Source
#![allow(clippy::all)]
// Stub — awaiting conversion from OCaml source.Deep Comparison
OCaml vs Rust: Continuation Passing
Overview
See the example.rs and example.ml files for detailed implementations.
Key Differences
| Aspect | OCaml | Rust |
|---|---|---|
| Type system | Hindley-Milner | Ownership + traits |
| Memory | GC | Zero-cost abstractions |
| Mutability | Explicit ref | mut keyword |
| Error handling | Option/Result | Result<T, E> |
See README.md for detailed comparison.
Exercises
sum_list(list: &[i32]) -> i32 to CPS and verify it produces identical results.map_k<A, B, K: FnOnce(Vec<B>)>(list: Vec<A>, f: impl Fn(A, Box<dyn FnOnce(B)>), k: K) — CPS map over a vector.