Functional JavaScript in 3 minutes: Is this function pure? Quick checklist
Remember functions from math class?
For every x, there is a corresponding y.
FP paradigm is based on this idea of treating functions as mathematical functions.
Functions should:
consistently produces the same output for a given input
does not cause observable side effects.
Everything that is not a function is a procedure.
Programming is not math. But certainly, we can take advantage of math in programming. There are many benefits of doing so, such as:
Easier to reason about
Easier to test
Easier to debug
The whys are a separate discussion. But for now, let's focus on what the headline of this article promised - the pure functions.
Pure Function
Always has output, for every input.
Check out the code below: What if the input is null or undefined? Or it's anything other than 'sunny,' 'rainy', or 'snowy'?
Below, we added a fallback. Now, we have an output for every input.
What about narrowing the range with TypeScript?
This function is pure - you are not allowed to pass anything other than 'sunny', 'rainy' or 'snowy' ✅
Of course, technically speaking, TypeScript is just a linter, and we are all going to hell for doing FP in JS, but this solution is good enough. This is a contract for developers, making it clear what the function can accept and what it returns.
The output is always the same for the same input.
Pure function - same input, same output:
Impure function - same input, different output:
No side effects
Modifying shared state (such as global variables, variables in parent functions scope)
is impure call - it modifies the outside world - global variable
Still impure - modifies the input object
What can we do about it?
Now, we are not modifying the input, we create a new copy of an object with the new copy of comments array. ✅
Making a network request:
As side effects are not avoidable in real-world applications, the way we often deal with that is by isolating pure and impure parts of the code.
For instance, instead of calling directly, we could return a function that will eventually make a network request:
By doing so, we can handle all side effects in one place, in a controlled way, and keep the rest of the code pure. ✅
Those were some examples of side effects, but there are many more. The point is, pure function should not alter, rely on, or interfere with anything outside of itself, in a way that is observable to the outside.
What it should do is reliably produce the same output for the same input, every time.
TLDR, is this function pure?
Always has an output for every input. ✅
The output is always the same for the same input. ✅