Skip to content
References and Mutable State
step 1/5

Reading — step 1 of 5

Learn

~1 min readMutable State and Combinators

OCaml is functional but allows mutation through ref. A ref is a single-cell mutable container.

let counter = ref 0

!counter         (* dereference: 0 *)
counter := 5     (* assign *)
counter := !counter + 1
incr counter     (* shortcut for ref-of-int: := !x + 1 *)
decr counter     (* := !x - 1 *)

ref x creates a new mutable cell. !r reads. r := v writes.

Use cases:

  • Loop counters and accumulators (when not using fold)
  • Caches
  • Simulation state

Arrays are also mutable:

let arr = Array.make 5 0
arr.(0) <- 10
arr.(1) <- 20
Array.iter print_int arr   (* 10 20 0 0 0 *)
Array.length arr           (* 5 *)

Hashtables for mutable maps:

let ht : (string, int) Hashtbl.t = Hashtbl.create 16
Hashtbl.add ht "alice" 30
Hashtbl.add ht "bob" 25
Hashtbl.find ht "alice"        (* 30 *)
Hashtbl.find_opt ht "carol"    (* None *)

Imperative loops with mutation:

let sum_to n =
    let total = ref 0 in
    for i = 1 to n do
        total := !total + i
    done;
    !total

Idiomatic OCaml prefers folds and recursion. Use mutation when it reads cleaner OR when performance matters (e.g., array updates).

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…