Commands and Sequencing
Commands as expressions
A command is informally an expression that has an effect on the state. In OCaml, all expressions return a value, but commands typically return () of type unit - a value carrying no information.
The sequence operator
The construct C₁; C₂; ...; Cₙ evaluates the expressions in order and returns the value of Cₙ:
let _ =
print_endline "Hello"; print_endline "World"; 42
(* prints "Hello" then "World", returns 42 *)
C₁throughCₙ₋₁are evaluated for their side effects; their return values are discarded.- Only
Cₙ’s value is returned. - The semicolons are the sequence operator.
Types flow through correctly: if C₁ : unit and C₂ : int, then C₁; C₂ : int.
Conditional commands
if-then-else works with commands naturally:
let _ =
if !balance >= amt then
(balance := !balance - amt; true)
else
false
Both branches must return the same type. The parentheses group sequenced commands into a single expression.
Pattern matching with commands
match also works with effects:
let _ =
match tlopt !lp with
| None -> fin := true
| Some xs -> lp := xs; np := !np + 1
Each match arm can be a sequence of commands. OCaml functions play the role of procedures - they can contain commands and be called for their effects.
Other languages
Languages that combine functional and imperative paradigms include Lisp (and its dialect Scheme), Scala, and older systems programming languages like BLISS. OCaml’s approach is distinctive in that functional purity is the default and imperative features must be explicitly opted into via ref and :=.