By definition, a Pure Function is pure if:
- Given the same input, will always return the same output.
- Produces no side effects.
- Relies on no external state.
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 bine 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"?
By definition, a Pure Function is pure if:
- Given the same input, will always return the same output.
- Produces no side effects.
- Relies on no external state.
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 bine 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"?
Share Improve this question asked Oct 27, 2016 at 9:29 kavarekavare 1,8062 gold badges19 silver badges27 bronze badges 11-
I guess as long as
foo
doesn't rely on any external state and doesn't change its behaviour based on any external statefoobar
will still be a pure function. – gurvinder372 Commented Oct 27, 2016 at 9:33 - yes, allowing bination does not break the fact that a function is pure. – Davin Tryon Commented Oct 27, 2016 at 9:33
-
In my understanding its not a pure function now. Function which does
Math.floor
will bee a utility function. Now if I change this utility function, all subscribers will be effected. Do utility function is pure but subscribers are not as they depend on utility. – Rajesh Commented Oct 27, 2016 at 9:34 - So even if a function relies on "external functions", such as 3rd-party libraries, it's still not treated as an "external state" ? – kavare Commented Oct 27, 2016 at 9:35
- @Rajesh that's exactly what I am concerned about – kavare Commented Oct 27, 2016 at 9:36
3 Answers
Reset to default 11External 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
.
How to test whether a function is pure
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 bees 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
.
I would argue that, in JavaScript,
function foo(x) {
return Math.floor(x);
}
is not a pure function. I would agree if Math
was only a namespace. But in JavaScript (AFAIK) it is a full featured mutable object. Therefor foo
relies on the state of the external Math
object and is not pure. One way to make it pure would be to use
const floor = Math.floor;
function foo(x) {
return floor(x);
}
That way, foo
would not depends on the state of the Math
object and is pure.