MLはいわゆる関数型言語とされており、破壊的代入などの副作用を無闇に使用することは一般に推奨されていません。が、必要な場合のために、命令型言語の機能も用意されています。たとえば、呼び出すたびに一つずつ増える整数を返す関数countは次のように書くことができます。
# let counter = ref 0 ;;
val counter : int ref = {contents = 0}
# let count () =
counter := !counter + 1;
!counter ;;
val count : unit -> int = <fun>
# count () ;;
- : int = 1
# count () ;;
- : int = 2
# count () ;;
- : int = 3
はじめのrefという演算子は、新しい格納場所(参照セル)を作って、与えられた値で初期化します。演算子!は、参照セルの現在の値を返します。:=は参照セルへの破壊的代入です。なので、たとえばcounter := !counter + 1は、参照セルcounterの値を一つ増やすことになります。...;...というのは式を順に評価する構文です。ただし;の前の式の値は捨てられてしまうので、ダミー値(unit型)以外だと警告されます。