Imperative Programming
ref is just type 'a ref = { mutable contents : 'a }.
16.1 References
ref is just type 'a ref = { mutable contents : 'a }.
let counter = ref 0 (* int ref *)
let () = counter := !counter + 1 (* := assigns, ! dereferences *)
let () = incr counter; decr counter
!counter16.2 Loops
There is no break/continue — use recursion, exceptions, or Seq instead.
for i = 1 to 5 do Printf.printf "%d " i done
for i = 5 downto 1 do Printf.printf "%d " i done
let i = ref 0 in
while !i < 5 do
print_int !i;
incr i
done16.3 Arrays — fixed-size, mutable, O(1) access
⚠️ Array.make 3 (Array.make 3 0) shares the *same* inner array 3 times — use Array.make_matrix or Array.init.
Bounds-checked: out of range raises Invalid_argument "index out of bounds".
let arr = [| 1; 2; 3; 4; 5 |]
arr.(0) (* 1 *)
arr.(0) <- 10
Array.length arr
Array.make 5 0 (* [|0;0;0;0;0|] *)
Array.init 5 (fun i -> i * i)
Array.map, Array.mapi, Array.iter, Array.iteri, Array.fold_left
Array.to_list, Array.of_list
Array.sort compare arr (* in place *)
Array.copy, Array.sub, Array.append, Array.concat, Array.blit, Array.fill
Array.exists, Array.for_all, Array.mem, Array.find_opt
Array.make_matrix 3 3 0 (* 2D array *)
Array.split, Array.combine, Array.to_seq16.4 Float arrays & Bigarray
float array is stored unboxed (flat doubles) — fast numerics.
Float.Array gives an always-flat float array.
Bigarray — large multidimensional numeric arrays, C/Fortran layout, memory-mapping, shared with C.
let m = Bigarray.Array2.create Bigarray.float64 Bigarray.c_layout 100 100
let () = m.{0, 0} <- 1.016.5 Dynamic arrays (OCaml 5.2+)
let d = Dynarray.create ()
let () = Dynarray.add_last d 1; Dynarray.add_last d 2
Dynarray.get d 0, Dynarray.length d, Dynarray.pop_last d16.6 When to go imperative
Mutation is fine when: performance demands it, it's localised (inside a function), or the algorithm is naturally imperative (graph search with visited arrays, dynamic programming). Keep public interfaces pure where practical.
(* Dynamic programming: longest common subsequence *)
let lcs a b =
let n = String.length a and m = String.length b in
let dp = Array.make_matrix (n + 1) (m + 1) 0 in
for i = 1 to n do
for j = 1 to m do
dp.(i).(j) <-
if a.[i-1] = b.[j-1] then dp.(i-1).(j-1) + 1
else max dp.(i-1).(j) dp.(i).(j-1)
done
done;
dp.(n).(m)