In progress

OCaml & OxCaml
drafts in flight

A top-down, opinionated learning resource for OCaml and OxCaml - aimed at the working engineer who's heard the hype and wants to evaluate it. Every post is a buildable artefact: vanilla OCaml first, OxCaml side-by-side where it earns its keep, with the gossip and timeline that make it stick.

The list below is a public commitment device. Each entry is a draft in some state - pending, being written, or shipped. The series is sequenced; the project stubs at the bottom are larger builds.

0 published0 drafting40 pending = flagship

Foundations

0108

Hardware up to OS - transistors, gates, CPU, memory bus, scheduling. Each post a buildable artefact. The hardware-end posts run side-by-side with Verilog and VHDL, with HardCaml (Jane Street's OCaml-as-HDL) closing the loop.

  • 01

    Modeling a CMOS transistor in OCaml

    A transistor is a switch: voltage in, on or off out. Model it as an ADT, pattern-match the behaviour, watch exhaustiveness checking become hardware correctness. Side-by-side: the same primitive in Verilog and VHDL, and where HardCaml lets OCaml describe the gate directly.

    Pending
  • 02

    Building a bit vector library from scratch

    Represent N-bit words as OCaml types. AND, OR, XOR, shift. Then OxCaml unboxed integers, side-by-side with the boxed version, and the perf delta on a real workload. Compared with Verilog's wire [7:0] and VHDL's std_logic_vector: what changes when bits are committed to silicon.

    Pending
  • 03

    Composing gates into an ALU - and a circuit diagram generator

    NAND from transistors → AND/OR/NOT → half-adder → full-adder → 8-bit ALU. Pure functions composing into bigger functions. The diagram generator emits Mermaid/DOT from the gate graph and gets reused throughout the rest of the series. Same ALU shown as a Verilog module and a VHDL entity; HardCaml as the bridge that keeps the description in OCaml all the way down.

    Pending
  • 04

    A tiny fetch-decode-execute loop in OCaml

    Eight instructions, eight registers. Instructions as variants. Write the interpreter - the Nand2Tetris CPU in OCaml - and verify it with property-based tests in QCheck. Compared with picorv32, a real synthesizable RISC-V core in Verilog: different language, same shape, very different consequences for verification.

    Pending
  • 05

    Modeling memory hierarchy with access latency

    Hierarchy as nested modules with different latency profiles. Cache locality affects simulated throughput. The fast path uses OxCaml's unboxed arrays. Diagrams via the post-3 generator.

    Pending
  • 06

    Disassembling OCaml: what does the native code actually look like?

    Compile OCaml to native, disassemble with objdump. Walk the x86 - prologue, tag checks, GC write barrier. Then OxCaml's local_ and what disappears from the assembly.

    Pending
  • 07

    Build a stack machine interpreter in OCaml

    Call stack as list, heap as hash map. Push, pop, call, return as pattern-matched ops. Then OCaml's runtime doing the same thing, and how tail recursion eliminates stack frames.

    Pending
  • 08

    Write a tiny OS scheduler in OCaml

    Processes as records, run queue as priority queue, time slices as integers. Round-robin first, then CFS-style vruntime. Gantt chart via the diagram generator.

    Pending

Finance modeled in OCaml

0912

Double-entry as a type constraint. Ledgers, statements, the accounting equation as typestate.

  • 09

    Model a double-entry ledger as an OCaml type system

    The TigerBeetle insight: double-entry is a type constraint. Make debits = credits enforced by the type system - unbalanced transactions don't compile. OxCaml modes lock posted transactions to immutable.

    Pending
  • 10

    A household ledger REPL in OCaml

    A tiny CLI ledger app: add income/expenses, query balance, export report. Builds on the type-safe ledger from post 9. Teaches dune layout, Cmdliner, S-expression serialization. First "real" tool in the series.

    Pending
  • 11

    The accounting equation as an OCaml typestate machine

    Assets = Liabilities + Equity as a phantom type. Typestate enforces that unbalanced ledgers can't be queried. OxCaml uniqueness makes the guarantee zero-cost at runtime.

    Pending
  • 12

    Generate financial statements from a ledger

    Balance sheet, P&L, cash flow as folds over an immutable transaction log. QCheck generates random valid transaction sets and verifies the accounting equation holds on every derived statement.

    Pending

Memory systems

1316

Caches, virtual memory, mmap, allocators. How a working engineer's mental model of memory maps to OCaml code.

  • 13

    Simulate the memory hierarchy with realistic latency

    Cache simulator: L1/L2/L3/RAM as chained modules returning (value, latency). Sequential vs random workloads. Plot the latency differences. SoA vs AoS via OxCaml in the simulator itself.

    Pending
  • 14

    Build a virtual memory system in OCaml

    Page table as a hash map, page fault handling, mmap/munmap. TLB as a tiny cache of recent translations. Diagram generator draws virtual → physical mapping as an annotated grid.

    Pending
  • 15

    OCaml's own mmap: memory-mapped files in practice

    Bigarray + Unix.map_file to actually mmap a file. 1 GB log reader. Measure mmap vs read(). Show the page-fault counter via /proc/self/stat. Connects to Irmin's content-addressed storage.

    Pending
  • 16

    Build a memory allocator in OCaml

    Bump allocator → free-list → buddy allocator on top of Bigarray. Compare to OCaml's own minor heap bump allocator. OxCaml local_ as the logical conclusion: allocation cost equals zero.

    Pending

Concurrency

1721

Races, memory ordering, lock-free structures, the case for OCaml 5 - and where the single-core bet wins anyway.

Runtime & observability

2225

Inside the OCaml runtime. Profilers, replay debugging, what domains are, what the scheduler is doing.

  • 22

    Build a memory profiler for OCaml programs using GC hooks

    Gc.create_alarm, Gc.stat, Gc.compact. A tiny profiler tracks allocation rates, GC frequency, live heap size. Profile a deliberately leaky OCaml program and find the leak.

    Pending
  • 23

    Deterministic replay for OCaml programs: what rr gives you

    An OCaml program with a deliberate intermittent data race. Normal debugging: bug disappears. With rr: record, replay deterministically, step backwards. Real rr replay + reverse-continue workflow.

    Pending
  • 24

    OCaml 5 domains are not threads: a mental model in code

    The same counter increment program in three forms: Unix threads, OCaml 5 domains, eio fibers. Threads need a mutex (slow); domains need Atomic (fast); fibers need neither (cooperative). Execution timeline diagram for all three.

    Pending
  • 25

    Implement CFS (the Linux scheduler) in OCaml

    CFS with OCaml's persistent balanced-tree Map as the run queue. Ten processes, 1000ms simulation, Gantt chart. Show how nice values distort fairness. OCaml's functional persistent map mirrors what CFS does mutably in the kernel.

    Pending

Kernel interface

2632

Syscalls, signals, cgroups, namespaces, seccomp, eBPF - all from OCaml. The OS through OCaml's eyes.

  • 26

    Hello World makes 50 syscalls. A MirageOS unikernel makes zero.

    Strace native OCaml print_endline - about fifty syscalls at startup for the linker, locale, TLS. The same logic as a MirageOS unikernel makes zero - no kernel underneath. The most visceral demonstration of what a unikernel is.

    Pending
  • 27

    Graceful shutdown done right: the self-pipe trick, then the eio version

    HTTP server two ways. V1: the self-pipe trick - signal handler writes one byte, event loop reads safely. V2: the same thing in eio where effects make signal handling look sequential. Why OCaml 5 effects matter for systems.

    Pending
  • 28

    Cage an OCaml program in a cgroup and watch the OOM killer strike

    A memory-hungry OCaml program in a 100MB cgroup via cgcreate/cgexec. Watch the OOM kill. Instrument GC behaviour approaching the limit. TigerBeetle's static allocation: set the cgroup to exact footprint, never be surprised.

    Pending
  • 29

    Build a 200-line container runtime in OCaml

    clone() via OCaml C FFI, spawn into fresh PID, mount and UTS namespaces, set hostname, chroot/pivot_root, run a shell inside. "Docker in 200 lines of OCaml." FFI to libc, namespace syscalls, what a container actually is.

    Pending
  • 30

    Wire two OCaml containers together with virtual networking

    Extend the container runtime: veth pair, bridge, IPs. Two OCaml containers ping each other. The diagram generator shows the packet path. Overlay-network teaser for cross-host. Kubernetes networking demystified by building its bottom layer.

    Pending
  • 31

    Sandbox an OCaml program with seccomp

    Use strace to discover the program's syscalls. Install a seccomp-BPF filter via FFI allowing only those. Demonstrate SIGSYS kill on a forbidden call. MirageOS minimal attack surface by construction vs seccomp as bolt-on.

    Pending
  • 32

    An eBPF syscall explainer, written in OCaml

    Attach eBPF from OCaml (libbpf FFI) to the sys_enter tracepoint. Capture and annotate every syscall a target process makes in plain English, real time. Run it against npm install or cargo build. Genuinely novel - no OCaml eBPF tooling, no educational annotator in any language. FP Launchpad collab thread.

    Pending

Debugging deep dives

3335

LD_PRELOAD, gdb on OCaml native, core dumps across the FFI boundary. The unglamorous craft.

  • 33

    Spy on OCaml's garbage collector with LD_PRELOAD

    OCaml's major heap is backed by C malloc. Write a malloc-interceptor .so, LD_PRELOAD it under an OCaml program, log every GC allocation to the C heap. Watch minor → major promotion live. Teaches dynamic linking, GOT, PLT. Bonus: why setuid binaries ignore LD_PRELOAD.

    Pending
  • 34

    Debugging OCaml native code in gdb: tagged values, mangled names, runtime frames

    OCaml native is real x86; gdb works but looks alien - camlModule__fn names, ints shifted left with a tag bit, pointers one word past the header. A real session: breakpoint, backtrace through caml_ frames, decode a tagged int by hand.

    Pending
  • 35

    Read an OCaml core dump after an FFI crash

    An OCaml program calls buggy C through the FFI and segfaults. Core dump, gdb, frame-0 null-deref pattern. Walk the stack from the C frame through the caml_ runtime back into OCaml code. Pinpoint the FFI boundary. OCaml is memory-safe until the FFI.

    Pending

I/O and async

3640

C10K, epoll, three async runtimes raced side-by-side, perf flame graphs, raw block devices.

  • 36

    C10K in OCaml: thread-per-connection vs eio fibers, benchmarked

    The same chat server, ten thousand idle plus a hundred active connections. Thread-per-connection (RAM explodes) vs a single eio event loop with fibers. Plot memory and throughput. C10K solved live, with numbers.

    Pending
  • 37

    Build an event loop in OCaml on raw epoll

    epoll_create1/ctl/wait directly via Unix FFI. Hand-roll an echo server event loop. The reveal: this is eio under the hood. Building the primitive makes eio stop being magic. Diagram generator for the readiness flow.

    Pending
  • 38

    Three OCaml concurrency models race: Lwt vs Async vs eio

    The same task (fetch ten URLs, combine) in Lwt (monadic), Async (monadic), eio (direct-style effects). The readability cliff. The OCaml concurrency evolution - 2008 Lwt, 2014 Async, 2022 effects - told as a code diff. The clearest argument for why OCaml 5 effects were worth an eight-year wait.

    Pending
  • 39

    Profile an OCaml hot loop with perf and a flame graph

    Allocation-heavy OCaml - boxing floats in a tight loop. perf record → flame graph → GC dominates. Diagnose boxing, fix with OxCaml unboxed floats, re-profile. GC frames vanish. The full perf-engineering loop with an OxCaml payoff.

    Pending
  • 40

    Talk to a raw block device from OCaml

    Open a loopback device with O_DIRECT via FFI, write sector-aligned blocks, read them back, bypass the page cache. Hit the alignment EINVAL footgun and fix it. TigerBeetle's storage philosophy in miniature. Connects to MirageOS's mirage-block typed module.

    Pending

Major projects

P1 – P3

Larger builds than a single post - ongoing projects with a technical thesis. Where they overlap with the numbered series, the post is the on-ramp and the project is the destination.

  • P1

    Syscall explainer in OxCaml + eBPF

    Watch what Claude Code does to your kernel in real time, annotated in plain English. No OCaml eBPF tooling exists today. FP Launchpad collaboration thread (Navaneeth Nambiar).

    Pending
  • P2

    Nand to Tetris in OxCaml

    Build a computer from logic gates up, entirely in OCaml. The "ground up" story told with full gossip and timeline - Tom Kilburn, Atlas, the whole arc.

    Pending
  • P3

    ripgrep-style Unix tool in OxCaml

    A performance story showing OxCaml's unboxed types and SIMD-via-layouts versus vanilla OCaml. A community motivator: "here is what OxCaml unlocks."

    Pending

Notes are authored in a separate workspace and converted to posts here. When a stub transitions from pending to drafting, it gets its own URL. Until then, anchor links above are stable.