Is this a pure function?
How about this?
Or this?
Well, what is a pure function?
A function is pure when given the same input, we always get the same output
Given 2 and 3 add
will always yield 5
Thus ✅. A pure function
Given no input getCurrentMonthIndex
will return us 9
as long as we are in October.
As soon as we enter November it will return the number 10
.
Same input - not same output.
Thus ❌. Not a pure function
Given the String "hello"
log
will always print "hello"
to the console.
Same input, same output. A pure function?
What if?
By redefining console
we changed the behaviour of our log
function.
Same input. Different output. As was expected.
❌ Not a pure function
So - How did we find out if these functions are pure?
Pretty much by reading the their implementation details.
Their function body.
And, of course, by testing (calling, invoking) them.
Super easy to do that with one-liners. Hard with functions spanning tens, hundreds or thousands of lines in length.
Can we rewrite both getCurrentMonthIndex
and log
to be pure?
Of course. We only need to declare their hidden inputs.
For the getCurrentMonthIndex
it is the new Date()
and for log
the console
.
Is this helpful code? Is this good code?
Up for the reader to decide.
Have we made the hidden inputs visible?
No, there is is still the this present in all JavaScript functions. It is hidden but its there.
Are the functions pure?
Depends. Whether we consider them are pure or not - we probably can agree that they are more pure than they were before.
How did we find out if these functions are pure?
We did so by reading their code. Their implementation.
There is no other way of knowing!
Even if we call them with multiple inputs and check the output it is hard to cover the full space of available inputs.
Especially in the JavaScript case above where the input could be any type. We can add the Strings '4' + '2'
and Numbers 4 + 2
.
Is there an alternative where we don’t have to read the code?
Let’s play with the programming language Haskell.
sayHello
takes a String
as an argument and returns a String
An equivalent to console.log()
would be putStrLn
Let’s use it inside of sayHello
Running this will give us an error.
String is expected and actual is IO ()
. The compiler does not allow us to do that.
We have to define the side-effect (putStrLn
) in the function definition.
So what?
We don’t have to read the implementation to learn whether the function is pure or not. Only the type signature!
A function taking String
as input and returning a String
as output is pure. It has to be.
Haskell is considered a purely functional programming language. Not because it has pure functions but because expressions in Haskell can be expressed exclusively in terms of a lambda calculus.
Lambda calculus?
Well, maybe something for our next post :)