'What exactly is a pure function when we are talking about a function within a function
I've learned that a pure function is a function that doesn't alter global state, period. If this is true, functions within functions can alter the state of the outer function and still be pure, correct?
Example:
function func1() {
let name = "My Name"
func2()
function func2() {
// alter name here.
}
}
In the above example, func2
is still pure because it doesn't use any global state.
That's how I see, but my working colleagues believe that func2
is not pure, and it should be writen like:
function func1() {
let name = "My Name"
func2(name)
function func2(name) {
// use name here.
}
}
Which is bad, because:
- if the v8 doesn't optimize this, the CPU will run more instructions
- shadowing is a bad practice
The question is: What exactly is a pure function when we are talking about a function within a function?
Solution 1:[1]
Purity is not defined to care only about global variables, it cares about any non-local variables (and more) that shouldn't be mutated. An outer variable of a closure still counts as non-local, it doesn't need to be global.
So if func2
changes name
, then it's impure. Whether func1
becomes impure as well through that depends on whether you consider only external purity - as long as name
and func2
stay local within the function, it may still be pure.
Solution 2:[2]
A pure function is a function that meets 2 requirements:
- Given the same input, it will always return the same output.
- Produces no side effects.
Side effects can be defined as 'any application state change that is observable outside the called function other than its return value'.
To be more specific:
A function that modifies anything outside it's scope (even if it's not the global scope) is not a pure function.
In your example, if func2 modifies a variable outside its own scope, then it's not a pure function:
function func1() {
let name = "My Name"; // <-- the variable is not in the global scope but, in any case, it is outside the scope of func2
func2();
function func2() {
// alter name here.
}
}
Solution 3:[3]
I've learned that a pure function is a function that doesn't alter global state, period.
Well, that's oversimplifying. A pure function should one, not have side effects, and two, its outcome should rely only on the arguments. So, as a corollary, no state. Your func1
's name
property suspiciously look like a state. Could I mutate it? Will func1()
yield different results dependent of the previous calls? Impure!
Of course, func2 being impure is beyond dispute. You wrote "alters name" - 'name' is outside its scope. It's a side effect.
Solution 4:[4]
Another example I think it's worth mentioning is the follow pure function:
function insert(DB, user) {
return function() {
throwIfUserExists(DB, user);
var savedUser = saveUser(DB, user);
return savedUser;
}
}
Note, that when you call insert
, as long as you keep sending in the same DB
and user
, you will receive the same output as the function returns another function - no side effect happens.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Bergi |
Solution 2 | |
Solution 3 | |
Solution 4 |