An article I was reading gives this as an example of an impure function (in JavaScript):
const tipPercentage = 0.15;
const calculateTip = cost => cost * tipPercentage;
That struck me as a bit of an odd example, since tipPercentage
is a constant with an immutable value. Common examples of pure functions allow dependence on immutable constants when those constants are functions.
const mul = (x, y) => x * y
const calculateTip = (cost, tipPercentage) => mul(cost, tipPercentage);
In the above example, correct me if I'm wrong, calculateTip
would usually be categorised as a pure function.
So, my question is: In functional programming, is a function still considered pure if it relies on an externally defined constant with an immutable value, when that value is not a function?
An article I was reading gives this as an example of an impure function (in JavaScript):
const tipPercentage = 0.15;
const calculateTip = cost => cost * tipPercentage;
That struck me as a bit of an odd example, since tipPercentage
is a constant with an immutable value. Common examples of pure functions allow dependence on immutable constants when those constants are functions.
const mul = (x, y) => x * y
const calculateTip = (cost, tipPercentage) => mul(cost, tipPercentage);
In the above example, correct me if I'm wrong, calculateTip
would usually be categorised as a pure function.
So, my question is: In functional programming, is a function still considered pure if it relies on an externally defined constant with an immutable value, when that value is not a function?
Share Improve this question asked Aug 14, 2017 at 10:33 samfrancessamfrances 3,6953 gold badges26 silver badges48 bronze badges 5- It is - in haskell every other function that "accepts more than 2 arguments" relies on the captured variables from the "outer scope". – zerkms Commented Aug 14, 2017 at 10:39
- Yes of course. Depending on immutable functions is just a special case of depending on immutable values. – Bergi Commented Aug 14, 2017 at 11:22
- If it weren't pure, maths would be broken. – molbdnilo Commented Aug 14, 2017 at 12:26
- Good question. Because if it wasn't then e.g. every function pertaining to circles would need to provide its own internal definition of Pi, which would add both duplication and risk. – Richard Pawson Commented Sep 30, 2017 at 15:58
- 2 I would be curious to see the article referenced (containing your first example)... – Tinynumbers Commented Oct 13, 2017 at 17:58
2 Answers
Reset to default 14Yes, it is a pure function. Pure functions are referentially transparent, i.e. one can replace the function call with its result without changing the behaviour of the program.
In your example, it is always valid to replace e.g. calculateTip (100)
anywhere in your program with its result of 15
without any change in behaviour, hence the function is pure.
Yes, theoretically, a function that abides by these two rules:
- not causing side effects
- not depending on "any mutable state"
can be considered pure, and as @TheInnerLight has put it well, provides referential transparency among other benefits. That makes the function in your example pure.
However, as the question is about & tagged with javascript
, it is important to note that a function that depends on a const
defined in the outer scope cannot always be considered pure:
const state = {}
function readState (key) {
return state[key]
}
// A hypothetical setState() can mutate `state` and
// therefore change the oute of `readState` calls.
That is obviously because state
value is not immutable (only the assignment is).
The rule of thumb is to prefer local over global when it es to scopes. That provides better isolation, debuggability, and less cognitive load for the next reader.