When we talk about functional programming very few things can be as important as pure functions. People who write code in this style make a considerable effort to contain as much logic as they can in pure functions, I'll try to explain some of the reasons behind this. But, first things first...
What's a pure function?
A function whose output is only determined by its input and has no observable effect on the outside world (has no side effects).
I want to focus on the benefits they provide to us humans who read and interpret code in our minds.
- They are predictable
Given the same inputs, it always produces the same output. This is one of the most relevant properties they have, and to me is the most important. It gives us the ability to test with relative ease how effective is our solution.
Say that we have a function that transforms every letter in a string to uppercase. What do we need to prove that it works? The function, some input data and the expected output.
to_uppercase('hello') == 'HELLO';
There is no need to emulate an entire environment or to use special tools, we just compare the result with the expected output. This gives us confidence in what we create, because we can prove with certainty that it works appropriately.
When it comes to code we spend more time reading and analyzing than writing it. Communication is one aspect that we always need to consider. In theory, a pure function would need the least amount of context in order to understand its behavior because everything you need to know about it is (or at least it should) in the body and its arguments.
Another property that pure function have is referential transparency, this means that we can replace a function call with its return value.
For example, this.
to_uppercase('hi') + ', user';
Can be replaced by this.
It means that when you understand what a pure function does you can mentally replace the function call with the return value.
If you have created a pure function there is a very strong chance that what you have is an independent component that can be reused in different contexts. Being independent and reusable makes them the perfect candidates to be combined with other components. Think about it, if you combine a pure function with another into a new function, it results in yet another pure function. This is one powerful feature allows you to create complex procedures by composing "simple" pieces.
As good as pure functions are at some point you need to abandon the idea of purity and cause some effect on the outside world (show something on the screen, make an HTTP request, etc..) Because of that I will share soon more articles that covers topics like composition techniques and how to deal with side effects.
- Functional Programming in JS: What? Why? How? (video)
- An introduction to functional programming
Thank you for reading. If you find this article useful and want to support my efforts, buy me a coffee ☕