Grand Synthesis
Tutorial Video
Text description (accessibility)
This video demonstrates the "Grand Synthesis" functional Rust example. Difficulty level: Expert. Key concepts covered: Functional Programming. This capstone example weaves together every major concept from this series: recursion schemes, optics, free monads, comonads, type-level programming, parser combinators, and categorical abstractions. Key difference from OCaml: | Aspect | Rust | OCaml |
Tutorial
The Problem
This capstone example weaves together every major concept from this series: recursion schemes, optics, free monads, comonads, type-level programming, parser combinators, and categorical abstractions. The goal is to build a small but complete functional language interpreter that demonstrates how these patterns compose: the AST is defined as a fixed-point type, evaluation uses a catamorphism, variable scoping uses the Reader monad, a free monad models effectful operations, lenses navigate nested state, and Cofree annotates the AST with type information.
🎯 Learning Outcomes
Code Example
#![allow(clippy::all)]
// Stub — awaiting conversion from OCaml source.Key Differences
| Aspect | Rust | OCaml |
|---|---|---|
| Recursive types | Box<ExprF<Expr>> | native recursive types |
| Pattern matching | exhaustive, verbose | exhaustive, concise |
| Free monad | trait objects | polymorphic variants |
| Lens | explicit get/set fns | record functional update |
| Effects | enum + interpreter | Effect library / algebraic effects |
| Performance | zero-cost abstractions | GC overhead, JIT optim |
The grand synthesis reveals the payoff of learning each abstraction individually: they compose cleanly, each handling one concern, and the Rust type system ensures each boundary is sound.
OCaml Approach
OCaml achieves the same architecture more concisely:
type expr_f = Lit of float | Var of string | Add of 'r * 'r
| Let of string * 'r * 'r | Lam of string * 'r | App of 'r * 'r
(* Catamorphism via fold *)
let rec eval env = function
| Lit n -> Ok (Num n)
| Var x -> List.assoc_opt x env |> Option.to_result ~none:(Printf.sprintf "Unbound: %s" x)
| Add (l, r) -> ...
| Let (name, v, b) -> eval env v >>= fun vv -> eval ((name, vv) :: env) b
| Lam (p, b) -> Ok (Closure (p, b, env))
| App (f, x) -> eval env f >>= function
| Closure (p, b, ce) -> eval env x >>= fun xv -> eval ((p, xv) :: ce) b
| _ -> Error "Not a function"
OCaml's algebraic types, pattern matching, >>= operator, and lack of explicit boxing make the interpreter visually cleaner while carrying the same categorical structure.
Full Source
#![allow(clippy::all)]
// Stub — awaiting conversion from OCaml source.Deep Comparison
OCaml vs Rust: Grand Synthesis
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
letrec) using a Rc<RefCell<Option<Value>>> thunk for self-reference.Type using the Cofree pattern.InterpreterState and compose them to build a transaction-style update that rolls back on error.