= Solution
An <ML reference type> `'a ref` describes a mutable cell holding a value of type `'a`. The operations are `ref : 'a -> 'a ref` for allocation, `! : 'a ref -> 'a` for dereferencing and `:= : 'a ref * 'a -> unit` for assignment. An immutable variable binding can name a mutable cell; assigning to the cell does not change what the binding denotes. Two names may alias the same cell, so an update through either is visible through the other.
``
val counter = ref 0;
val alias = counter;
counter := !counter + 1;
``
Both dereferences now give one. A reference's stored type remains fixed; the value restriction prevents allocating one unrestricted polymorphic cell and then using incompatible instantiations.
<Imperative programming> uses sequencing `(e1; e2; ...; en)` to perform effects left to right, with the final expression supplying the result. Conditional expressions choose one branch. `while condition do body` repeatedly checks a Boolean condition and performs a unit-valued body, returning `()` on termination. <Standard ML> has no required primitive `for` loop, but recursion or a reference with `while` supplies one. For example:
``
fun sumTo n =
let val i = ref 1
val total = ref 0
in
while !i <= n do
(total := !total + !i; i := !i + 1);
!total
end;
``
\b[References provide mutable state; sequencing, conditionals and loops control its updates.]
Back to article page