Why is this implementation of a pure function not considered external?

I am fine with the concept of pure function on fairly simple examples like ...

 function addTwo(val){ return val + 2; } 

Given the same arguments, it gives the same result, which leads to referential transparency and good deterministic code.

But then I came across such examples (taken from professor frisby of basically an adequate guide , but I found similar examples on other FP JS)

 //pure var signUp = function(Db, Email, attrs) { return function() { var user = saveUser(Db, attrs); welcomeUser(Email, user); }; }; var saveUser = function(Db, attrs) { ... }; var welcomeUser = function(Email, user) { ... }; 

and I don’t understand why it is not considered an external dependency (so unclean) to call saveUser or welcomeUser .

I know that from the point of view of the / IO function, signUp always returns the “same” (equivalent) wire function, but it seems strange to me.

It’s hard for me to understand why even

 function multiplyBy(times){ return value => value * times; } const fiveTimes = multiplyBy(5); fiveTimes(10); 

considered pure . From the returned POV function, access to times is a search in the chain of visibility areas, it can be obtained from the immediate external region or because of it (for example, the global region).

Does anyone want to bring some light?

+7
javascript functional-programming pure-function
source share
2 answers

My explanation for the purity of a function in JavaScript is that there is no such thing as a binary “clean” or “unclean”, but rather a spectrum of confidence that the function will behave predictably. There are all kinds of tricks that you can play to make a function that seems clean, cannot be, for example, passing an object using a side effector on it.

So, once we realize that cleanliness is a degree of certainty, we can ask how confident I am that a function will behave as I expect it to? If this function refers to another function, how confident are you that the other function is pure? And, moreover, how confident are you that an identifier that references this other function cannot / cannot be reassigned to point to another function that you are not aware of?

I personally program my programs so that I almost never redefine the identifier pointing to a function, especially if this function is declared, and not just a function expression. That way, I feel very confident (say 99.99%) that if foo(..) calls bar(..) and I'm sure bar(..) reliably clean, then foo(..) also reliably clean, because I know that I am not reassigning bar(..) to any other function and causing unexpected results.

Some people even go so far as to define their function identifiers with const fn = function .. I don’t think it helps that much ... probably my confidence level will reach 99.99% to 99.999%. This does not move the needle too much to warrant its use, IMO.

Also, in the closing part of your question: if an internal function is closed above an external variable that is still contained in a pure function and nothing is resetting this variable, then it is effectively constant, so my confidence level is very high in predictability.

But then again, pick up is that the purity of a function in JS is a level of confidence, not an absolute binary yes or no.

+16
source share

Definition of a pure function:

A function that always evaluates the same value of the result, given the same value (s) of the argument, and this does not cause any semantically observable side effects or results, such as mutation of mutable objects or output to input / output devices.

"Dependencies" absolutely does not play a role in determining a pure function. The only thing that matters is whether the function has any side effects and whether its result depends on the external state . If a function behaves in exactly the same way and always gives the same result with the same input, it is clean. If a function has any side effects (changes the global state) or behaves differently depending on the external state, it is unclean. A function may have a dependency on (read: call) another function as part of its operation; while this other function is also pure, which does not impair cleanliness.

The signUp example you are showing is clean, because it only affects its input and always returns the same output when called with the same input. Note that the function itself does nothing. It does not invoke a database or create side effects. All he does is return a function. But this return function is always the same if the input signal is the same. This returned function is unclean; but the function that created it is not.

+5
source share

All Articles