Is the view
function shown below, a pure function?
function view(model) {
return div([
heading,
`Home: ${model.home}, Away: ${model.away}`
])
}
I'm not sure, I need more information.
Ok, what else would you like to know?
What language is this written in?
JavaScript
What type of value is
heading
?
Here's where it's assigned:
const heading = header('Current Score')
Hmm, I still don't know what type of value
heading
is?
Take a guess. Do you think it's a primitive type (Number, String, etc..), or a non-privitive?
It's probably a non-primitive
That seems pretty reasonable to me, it almost has to be some form of an object.
What else would you like to know?
Are the
div
andheader
functions pure?
Well, they both come from a 3rd party library. The docs say they're pure functions... Let's take the authors word, and we'll assume they're pure.
Ok, back to the original question, is the view
function pure?
function view(model) {
return div([
heading,
`Home: ${model.home}, Away: ${model.away}`
])
}
It's impure
Why is that?
Well, we determined that
heading
is some form of an object, and objects can be mutated, in other words it's potentially stateful.
Now, since the view function depends on a stateful value that's not passed in as a parameter, it's impure.
How sure are you, any doubt in your mind?
I'm very confident
I'm going to disagree. I think the view
function, might be a pure
function.
Am I crazy?
Probably, but go ahead and give me an explanation
Ok, I'll give you one, but let's consider another example first.
Is the following function pure?
function add(a, b) {
return a + b;
}
That's easy, it's a pure function.
Are you sure?
Yes, it's the canonical example of pure functions, right?
Would you believe me if I said the add
function might not be pure?
Probably not, I think you should go check your temperature, I'm guessing you've got a fever
Ok, before you attack me, give me a bit of leeway and let me explain.
Technically someone could hijack the add function, as shown below:
const _add = add;
add = (a, b) => {
launch();
return _add(a, b)
}
function launch() {
console.log('Missle Launched!');
}
//...
console.log(add(1, 2));
// "Missle Launched!"
// 7
That's ridiculous, nobody would do that
I agree, it seems very unlikely, but if we're being sticklers, you can't be
sure that calling add
will be side effect free, can you?
What's the point?
Humans don't like ambiguity. We want certainty, we want things to be black and white, but the truth is, we find ourselves in gray areas most of the time.
For instance, consider the view
function you saw earlier.
We determined it has characteristics that might make it impure... So most people
would call it impure. But the truth of the matter is, it might be impure, and
it might be pure.
It might be impure because it depends on the potentially stateful value,
heading
, but what if I could say with certainty, heading
, never get's
changed.
Wouldn't you call the view
function pure in this scenario?
But how could you know with certainty, that
heading
never get's mutated?
Well, I can't be 100% certain, but I can have high confidence.
What if the object that's returned from the header
function, is frozen.
But freezing is only shallow
Ok, what if it's frozen to all depths?
Or, what if I added lint rules to my build process, that forced me to program in a functional style?
Then I could have high confidence that the heading
object never get's
mutated, in which case the view
function would seem to be pure.
Similarly, with the add
function, I could setup lint rules to prevent the
hijacking of the add function.
Am I just being a contrarian
I get a lot of questions from programmers taking my courses. Many of these folks are looking for binary answers to their questions. But the truth is, many questions don't have binary answers.
For example, "is this function pure?"
Sometimes the answer is yes or no, but sometimes I'd say functions are effectively pure, but I'd hesitate to say YES they are 100% pure.
Searching for answers, can be frustrating, when we're only considering 2 possible choices. Embrace the gray areas, because that's where most of the answers are.