You remember that Functional Programming (FP) is all about function composition? But what’s composition by the way? Let’s explain it here with a few other useful concepts for FP, and go one step further in monads understanding.
A composition of integer in mathematics is a way of writing N as the sum of a sequence strictly positive. Weak composition is for sequence positive or equal to zero. It means that every positive integer admits infinitely many weak compositions. 0 is also known as the neutral element for the set of integers.
A function composition is when we apply a function (say f) to the result of another one (say g) to produce a third function (say h). We write it h=g°f. Intuitively, composing two functions is a chaining process in which the output of the inner function becomes the input of the outer function. This is in essence functional programming.
A function that returns exactly its input as the output without any alteration is also known as the identity function. There is a symetry between weak composition of integers and weak composition of functions, because an identity function is a neutral element for the set of functions. Like 0 for integers, it can help in several situations to allow more composition. Which is useful, because we want to compose everything!
Which functions are composable?
Two functions are composable if their Domain and Co-Domain are compatible. Let’s imagine two functions:
- StringToInt : s (string) -> i (integer) StringToInt is a function mapping a string (Domain) with an integer (Co-Domain).
- TwoTimes: i (integer) -> o (integer) TwoTimes is a function mapping an integer (Domain) with another integer (Co-Domain).
Can I imagine a composition TwoTimes>>StringToInt? No because TwoTimes output is an integer, and StringToInt input is a string. The Co-Domain of TwoTimes is not compatible with the Domain of StringToInt. But the Co-Domain of StringToInt is compatible with the Domain of TwoTimes. Thus, we could define a correct composition StringToInt>> TwoTimes. Most FP patterns are just a way to wrap data so that Domain and Co-Domain stay compatible, thus composable, despite side effects.
Composable functions properties
If functions are composable, they are associative. It means: g°f(x) = g(x)°f . You know for example that addition is associative.
So if g is +5, f is +10 and if x is 3, we can write: 5+ (3+10) = (5+3) + 10 = 18.
Note that, if two functions have the same Domain and Co-Domain, they are composable, and because they are composable they are also associative. The composition of functions with the same Domain and Co-Domain are called transformations, because mathematicians like to give a name to everything (and for once it seems a logical name).
How powerful is function composition?
In a few words: it allows to express complex things in a simple form. In physics for example, Lorentz Transformations are very famous. Using a series of transformation, Lorentz showed that the speed of light is the same in all inertial reference frames. The invariance of light speed is one of the postulates of Einstein’s Special Relativity theory.
Of course we’re not Einstein, but expressing complex things in a simple form is definitely something interesting for software design.