21

Here's an example of an higher order function called functionA that has customValue as input and returns a function that gets an input and uses the custom value to elaborate a result:

let functionA = (customValue) => {
  let value = customValue || 1;
  return input => input * value;
};

Here's some results:

functionA()(4)             
// => returns 4

functionA(2)(4)
// => returns 8

functionA(3)(4)
// => returns 12

functionA(4)(4)
// => returns 16

Can the function returned by functionA be considered pure?

UPDATE: the examples above are only using numeric input. As described by @CRice, the returned function can be considered pure only when customValue is constant and doesn't have internal state (like classes).

Francesco Meli
  • 2,484
  • 2
  • 21
  • 52
  • 5
    There is healthy, meaningful discussion in the community about what "pure" means for functions. One (over?-)simplified definition is "no side effects"--no impact on variables/state outside the function scope that would make the function have different effects with the same input. Your functionA definitely meets that criterion. I say yes. – Andy Taton Aug 22 '18 at 02:28
  • 4
    If you only consider reasonable input, i.e. `number` (or BigInt, now) – see CRice’s answer – then yes, it’s pure. – Ry- Aug 22 '18 at 02:42
  • 2
    Some kindly folks upvoted my comment, but it's clear I misinterpreted the question. You did not ask "Is functionA pure?", but rather "Is the function returned by functionA always pure, by virtue of functionA?" As someone else answers below, I think the answer to this second question is "no". – Andy Taton Aug 22 '18 at 02:45
  • Puzzles in JS are hard to solve with [many kinds of overloading available](https://stackoverflow.com/questions/48270127/can-a-1-a-2-a-3-ever-evaluate-to-true). (same for C++) – user202729 Aug 22 '18 at 07:30
  • For OP: Don't edit the answer into the question. If you want to answer post an answer. – user202729 Aug 22 '18 at 07:31
  • @pnknrg Not only the returned function is pure, but also the whole `functionA` should be considered pure – Bergi Aug 22 '18 at 07:43
  • @AndyTaton What other definitions are there? Especially, are there any where it would be considered impure? – Bergi Aug 22 '18 at 07:45
  • The question was edited since my comment. I don't think my caveat applies any more. – Andy Taton Aug 22 '18 at 13:01

3 Answers3

23

Using this definition of Pure Function:

In computer programming, a pure function is a function that has the following properties:

  1. Its return value is the same for the same arguments (no variation with local static variables, non-local variables, mutable reference arguments or input streams from I/O devices).

  2. Its evaluation has no side effects (no mutation of local static variables, non-local variables, mutable reference arguments or I/O streams).

Then, no, functionA will not always return a pure function.

Here is a way to use functionA so that it does not return a pure function:

let functionA = (customValue) => {
  let value = customValue || 1;
  return input => input * value;
};

class Mutater {
  constructor() {
    this.i = 0;
  }
  valueOf() {
    return this.i++;
  }
}

const nonPureFunction = functionA(new Mutater());

// Produces different results for same input, eg: not pure.
console.log(nonPureFunction(10));
console.log(nonPureFunction(10));

As you can see, the returned function, when given the same input (10), produces a different result. This violates the first condition from the above definition (and using the same trick you could also violate the second).

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
CRice
  • 29,968
  • 4
  • 57
  • 70
  • 8
    so we can say that as long as customValue doesn't have internal state then the function returned by functionA is pure. Correct? – Francesco Meli Aug 22 '18 at 02:50
  • I would say yes, as long as `customValue` is constant. But you can also pass `mutator` as the argument to the returned function for the same kind of shenanigans. But would that still count as the "same input"? I don't know. – CRice Aug 22 '18 at 02:55
  • @pnknrg Would reading from e.g. a stream be considered "internal state"? I think one could just stick with the Wikipedia definition to find that `functionA` is pure if `customValue` is pure. – Max Langhof Aug 22 '18 at 09:46
  • As long as you have mutable data types like Object in JS you will not have pure functions. JS is just a toy language trying to implement functional programming paradigm. With primitive data types like String this might not be the case though. – Redu Aug 22 '18 at 19:17
3

Yes, the function that is returned, can be considered pure. The reason that it is considered pure, is because the function will always return the same output given the exact same input.

0

Your returned functions can be considered as pure function. In your example, you have effectively 4 different pure functions.

const pureFunc1 = functionA();
pureFunc1(4)   // => returns 4
pureFunc1(4)   // => returns 4

const pureFunc2 = functionA(2);
pureFunc2(4)   // => returns 8
pureFunc2(4)   // => returns 8

// ...
engineforce
  • 2,840
  • 1
  • 23
  • 17