7

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

11
  • I guess as long as foo doesn't rely on any external state and doesn't change its behaviour based on any external state foobar will still be a pure function. Commented Oct 27, 2016 at 9:33
  • yes, allowing combination does not break the fact that a function is pure. Commented Oct 27, 2016 at 9:33
  • In my understanding its not a pure function now. Function which does Math.floor will become a utility function. Now if I change this utility function, all subscribers will be effected. Do utility function is pure but subscribers are not as they depend on utility. Commented Oct 27, 2016 at 9:34
  • So even if a function relies on "external functions", such as 3rd-party libraries, it's still not treated as an "external state" ? Commented Oct 27, 2016 at 9:35
  • @Rajesh that's exactly what I am concerned about Commented Oct 27, 2016 at 9:36

3 Answers 3

11

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for you example for multiplication I think it demystify a lot of things. However, one selling point for Pure Function is that they are always independent, so it's easy to pull and plug between different code modules. If a Pure Function does allow an underlying dependency for a function coming from else where (i.e. not pass in as an argument), how would the consumer for that function know there's a implicit dependency?
That's a matter of how dependencies are handled in your language of choice. "Pull and plug" hopefully doesn't mean copy and paste, right? What you mean is that you import some_module and use some_module.some_function(), or however it works exactly in your language of choice. That leaves some_module entirely free to lay out its code however it likes, including dependencies.
Then it doesn't really matter what source code exactly is needed for some_function. There's little difference between needing to copy and paste (no no!) or install/import one function/module/dependency and a whole bunch of them. You simply need to have access to all the relevant source code if you want to call that function. That's an entirely different concern than whether the function behaves purely or not.
Yeah, I think you are right to assume that "reuse" of a function should comes from package import level instead of simple copy & paste :) Thumbs up.
And even if it was copy and paste: what's the difference between copy and pasting one giant function or several smaller functions which all belong together? Again: it's a mere syntactical difference.
1

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 .

Comments

0

I would argue that, in JavaScript,

function foo(x) { return Math.floor(x); } 

is not a pure function. I would agree if Math was only a namespace. But in JavaScript (AFAIK) it is a full featured mutable object. Therefor foo relies on the state of the external Math object and is not pure. One way to make it pure would be to use

const floor = Math.floor; function foo(x) { return floor(x); } 

That way, foo would not depends on the state of the Math object and is pure.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.