Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why this implementation of a pure function isn't considered to have external dependencies?

I'm fine with the pure function concept on pretty simple examples like...

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

Given the same arguments, it yields the same result, leading to Referential Transparency and good deterministic code.

But then I've came across examples like these (taken from professor frisby mostly adequate guide, but I've found similar examples on other FP JS books)

//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 get why isn't considered an external dependency (so, impure) the call to saveUser or welcomeUser.

I know that from a function/IO point of view, signUp always return the "same" (an equivalent) wired function, but it feels weird to me.

It's difficult to me to understand why even

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

is considered pure. From the returned function POV, accesing to times is a lookup on the scope-chain, it could come from the immediate outer scope, or from beyond (like global scope).

Any one wants to bring some light to this?

like image 764
sminutoli Avatar asked Oct 03 '16 14:10

sminutoli


People also ask

Why do we need to declare a function as pure?

Pure functions are much easier to read and reason about. All relevant inputs and dependencies are provided as parameters, so no effects are observed that alter variables outside of the set of inputs. This means that we can quickly understand a function and its dependencies, just by reading the function's declaration.

What are the qualities of a purely functional program?

Purely functional programming consists of ensuring that functions, inside the functional paradigm, will only depend on their arguments, regardless of any global or local state. A pure functional subroutine only has visibility of changes of state represented by state variables included in its scope.

What are dependencies in pure functions?

one way to make functions with side effects into pure functions is to use dependencies. in this approach any side effects are placed into function parameters. they can be treated as some other functions responsibility. this is called dependency injection.

What does it mean for a function to be pure?

A Pure Function is a function (a block of code) that always returns the same result if the same arguments are passed. It does not depend on any state or data change during a program's execution. Rather, it only depends on its input arguments.


2 Answers

My explanation for function purity in JavaScript is that there's no such thing as a binary "pure" or "impure", but rather a spectrum of confidence that a function will behave predictably. There's all kinds of tricks that can be played to make a function that seems pure not be, by passing an object with a side-effect getter on it, for example.

So, once we realize that purity is about degree of confidence, we can then ask, how confident am I that some function will behave the way I expect? If that function references another function, how sure are you that the other function is pure? And, moreover, how sure are you that the identifier that's referencing that other function doesn't / can't get re-assigned to point to some other function you aren't aware of?

I personally code my programs so that I almost never re-define an identifier that's pointing at a function, especially if that function is declared rather than just a function expression. In that way, I feel very confident (say, 99.99%) that if foo(..) calls bar(..), and I'm confident that bar(..) is reliably pure, then foo(..) is also reliably pure, because I know I won't reassign bar(..) to any other function and cause surprising results.

Some people even go so far as to define their function identifiers with const fn = function ... I don't think that helps all that much... it probably would take my confidence level from 99.99% to 99.999%. That doesn't move the needle enough to justify its usage, IMO.

Moreover, on the closure part of your question: if an inner function closes over an outer variable that's still contained in a pure function, and nothing re-assigns that variable, then it's effectively a constant, so my level of confidence is very high in the predictability.

But again, the take away is that function purity in JS is about level of confidence, not an absolute binary yes or no.

like image 82
Kyle Simpson Avatar answered Sep 24 '22 23:09

Kyle Simpson


The definition of a pure function is:

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

"Having dependencies" plays absolutely no role in defining a pure function. The only thing that matters is whether the function has any side effects and whether its result depends on external state. If a function behaves exactly the same and always produces the same result given the same input, it is pure. If a function has any side effects (modifies global state) or behaves differently depending on external state, it is impure. A function may have a dependency on (read: call) another function as part of its operation; as long as that other function is also pure, that doesn't taint the purity.

The signUp example you show is pure, because it only acts on its input and always returns the exact same output when called with the same input. Note that the function itself doesn't "do" anything. It's not calling the database or produce any side effect. All it does is return a function. But this returned function is always the same if the input is the same. That returned function is in effect impure; but the function that produced it is not.

like image 24
deceze Avatar answered Sep 21 '22 23:09

deceze