(* ML does support imperative-style variables (i.e. where the value associated with a variable can be changed by assignment) -- they are called reference variables. The following illustrates how reference variables are created, updated, and used. This also illustrates one of the rare programs where reference variables are necessary. Finally it highlights the fact that "local" variables are allocated once (whereas "let" variables are re-allocated on every function invocation. *) (* Linear Congruential Random Number Generator. Returns an integer in [0,728] *) local val seed = ref 261 (* reference variables are declared by assigning them "reference values" (e.g. ref 261) *) val modulus = 729 val multiplier = 40 val increment = 3641 in fun random _ = let val _ = seed := (multiplier*(!seed)+increment) mod modulus in !seed (* ! is the dereference operator. *) (* := is assignment ... Note that there's no "ref". Assignment is purely a side-effect; the value it returns as a function is () ("unit") *) end fun randombool _ = (random ()) < (modulus div 2) end;