Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a nested pure function still a pure function?

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 combine 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"?

like image 503
kavare Avatar asked Oct 27 '16 09:10

kavare


2 Answers

External 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.

like image 124
deceze Avatar answered Nov 11 '22 10:11

deceze


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 becomes 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 .

like image 26
rabbitco Avatar answered Nov 11 '22 10:11

rabbitco