Skip to content
Part IA Michaelmas Term

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.

ConceptIn mathematicsIn OCaml
FunctionInfinite uncomputable mappingComputable algorithm
FunctionalE.g. differentiation operatormap, 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.