Delimited Continuations
Tutorial Video
Text description (accessibility)
This video demonstrates the "Delimited Continuations" functional Rust example. Difficulty level: Expert. Key concepts covered: Functional Programming. Full continuations (`callcc`) capture the entire remaining computation. Key difference from OCaml: 1. **Native support**: OCaml 5's effect system is built on delimited continuations; Rust requires simulation or `unsafe` code.
Tutorial
The Problem
Full continuations (callcc) capture the entire remaining computation. Delimited continuations capture only the computation up to a "delimiter" — a prompt that marks the boundary. This makes them composable and less dangerous than full continuations. Delimited continuations are the foundation of effect handlers (OCaml 5), generators, and async/await. Understanding them reveals how all these features share a common computational model.
🎯 Learning Outcomes
reset (sets the delimiter) and shift (captures the delimited continuation)Code Example
#![allow(clippy::all)]
// Stub — awaiting conversion from OCaml source.Key Differences
unsafe code.continue k can be called multiple times (non-determinism, backtracking); Rust's FnOnce and Box<dyn FnOnce> are single-shot only.match_with; Rust's simulation composes poorly beyond simple cases.OCaml Approach
OCaml 5 implements delimited continuations natively:
let () =
match_with (fun () ->
let k = perform (Shift (fun k -> k)) in (* capture delimited cont *)
Printf.printf "resumed\n";
perform (Resume k) (* resume it *)
) () { ... }
The delimcc library (for older OCaml) provides new_prompt, push_prompt, and shift0 / control0 as the full delimited continuation API.
Full Source
#![allow(clippy::all)]
// Stub — awaiting conversion from OCaml source.Deep Comparison
OCaml vs Rust: Delimited Cont
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
yield_value shifts, next_value resets.amb([1, 2, 3]) tries all options using multi-shot continuation semantics.reset/shift combination that implements Result propagation — shift throws an error, reset catches it.