By definition, a Pure Function is pure if:
So this is a pure function:
function foo(x) {
return x * 2;
}
foo(1) // 2
foo(2) // 4
foo(3) // 6
And this would be a pure function as well (in JavaScript context)
Math.floor(x);
Math.floor(1.1); // 1
Math.floor(1.2); // 1
Math.floor(2.2); // 2
The question: if we combine these 2 pure function, would it still be considered as a pure function?
// Nested with Math library
function bar(x) {
return Math.floor(x);
}
// Nested even deeper
function foobar(x) {
return foo(Math.floor(x));
}
Obviously, it still always return the same output given the same input without side effects, but does calling a function from other context (scope) break the law for "Relies on no external state"?
External state is different from external code. If pure functions couldn't use external code, then there pretty much would be no such thing as a pure function at all. Even if all your function does is x * 2
, in (many) pure functional languages even *
is a function. So even this simple function cannot avoid calling other functions.
Function definitions are more or less just syntax details. You could inline the function body of external functions into a longer expression. E.g.:
function foo(a, b) {
return bar(a) + bar(b);
}
function bar(x) {
return x * 2;
}
is identical to:
function foo(a, b) {
return a * 2 + b * 2;
}
The only difference is reusability of code snippets and/or readability and maintainability. Not purity.
A function is pure if it doesn't cause side effects or is influenced by side effects/state outside itself. It stays pure as long as all the code it calls also conforms to that rule.
Does calling a function from other context (scope) break the law for "Relies on no external state"?
Not if the link between arguments
and return value
is still pure.
A pure function maps an input (arguments
) to an output (return value
) in a way that can be predicted with an 100 % accuracy solely based on the arguments
and without containing any other code than that necessary to produce the return value
.
You can apply this simple test to determine whether it is pure:
function multiplication (integer) {
var result = 2 * integer;
return result;
}
console.log(multiplication(4)) // 8
What will always be true about multiplication(integer)
is that you in your code can simply replace a call to it by the return value
it produces for a given argument
. That is in stead of writing multiplication(4)
in your code you could just write 8
. This test fails as soon as the function becomes impure:
function multiplicationImpure (integer) {
var result = 2 * integer;
console.log (result);
return result;
}
console.log(multiplicationImpure(4)) // 8 8
Now if you where to replace multiplicationImpure(4)
with 8
in your code it would no longer be the same: there would be missing one 8
in the output to the console. Likewise simply putting 8
in your code would be a problem if some external state could result in another return value than 8
for the argument 2
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With