Functions as Values
Functions as first-class values
In OCaml, functions can be:
- passed as arguments to other functions
- returned as results from other functions
- put into data structures like lists, trees, and tuples
- but not tested for equality (comparing function addresses would test identity, not equivalence)
[(fun n -> n * 2); (fun n -> n * 3); (fun n -> n + 1)]
(* : (int -> int) list = [<fun>; <fun>; <fun>] *)
This is a list of three functions, each of type int -> int. Storing computational behaviour in data structures is a powerful abstraction that reaches its full realisation in object-oriented programming.
Higher-order functions (functionals)
A functional or higher-order function is a function that operates on other functions - either by taking them as arguments or returning them as results. The name comes from mathematics: the differential operator maps functions to their derivatives.
| Concept | In mathematics | In OCaml |
|---|---|---|
| Function | Infinite uncomputable mapping | Computable algorithm |
| Functional | E.g. differentiation operator | map, filter, exists |
Why functions as values matter
Progress in programming languages can be measured by what abstractions they admit. Conditional expressions replaced numeric-sign-based jumps. Parametric types like 'a list gave us type-safe generics. Functions-as-values is the next step: it captures common program structures once and for all.
- Avoids writing repetitive recursive functions for similar patterns
- Lets you define ad-hoc operations inline without naming them
- Enables libraries of combinators (
map,filter,fold, etc.) that generalise across many domains - Is the foundation of Church’s λ-calculus, which is equivalent in power to Turing machines and is the direct precursor of
fun-notation
Key limitations
- Functions cannot be tested for equality in OCaml. Two separately compiled functions that compute identical results are not considered equal; the comparison would reduce to comparing machine addresses, which is a low-level detail with no place in a principled language.
- Functional arguments and results must have consistent types enforced by the type checker at compile time.