I’ve already1 attempted to define functional programming (FP), but I wasn’t satified with it. Kris Jenkins did a much better job, and wrote a couple of very good posts on this:
But recently I’ve come across the definition of Graham Hutton in his book2, “Programming in Haskell” (second edition, 2016).
And something clicked. I really like it since it’s concise and other things (like purity and immutability) are consequences. Here it is, slightly modified3:
A function is a mapping between one or more arguments and a single result. It’s defined using an equation that gives a name to the arguments and a body that specifies how the result is calculated in terms of the arguments.
For example:
double x = x + x
Where:
double
is the name of the function.x
is the single argument.x + y
is the specification of how the result is calculated in terms of the argument.I’ve emphasized some keywords that highlights the central idea: a function is defined by an equation that specifies (describe) how the result is calculated in terms of the arguments. By this definition we can derive some important properties:
What other languages call functions4, by this definition are really other things: procedures or methods.
So, what is FP? It’s just programming with functions :)
Another interesting consequence of that definition, is the substitution model:
When a function is applied to some values, the result is obtained by substituting those values in the body of the function in place of the argument names.
The result of this substitution and evaluation can sometimes be a single result, but often a function is defined in terms of other functions. In that case, we can continue to perform substitutions until we can reduce the whole program to a final result5. In other words, every program che be represented by a single equation.
When programs are defined this way, they are easier (for both programs and humans) to understand, reason about and manipulate. And we are not talking about a type system6 yet!
Another way to look at purity that follows from this substitution model, is referential transparency. It has been defined by Rúnar Bjarnason as follows:
An expression
e
is referentially transparent if for all programsp
, every occurrence ofe
inp
can be replaced with the result of evaluatinge
without changing the result of evaluatingp
.A function
f
is pure if the expressionf(x)
is referentially transparent for all referentially transparentx
.
This may seem obscure, pedantic and/or irrelevant, but it’s something profoundly practical and with deep ramifications.
BTW, this is also the reason why “mostly functional” programming doesn’t work.