Pure Programming

Alan Devlin
3 min readApr 11, 2018

--

The concept of purity (also called referential transparency) is very important in functional programming. In fact, you could say that functional programming is programming that aims for purity. So what is purity? It means you can’t have side effects. The term ‘side effect’ does not refer to the common phrase used in medicine to mean unintended outcomes. Let me illustrate what a side-effect is in programming with a diagram.

a pure function

If you look at a function as a picture, a pure function just takes an input and returns an output.

Here I have a function called myFunction which sits in the rest of my application. myFunction takes an input of 3 and returns an output of 9*.

If we consider the definition of the word effect:

a change which is a result or consequence of an action or other cause

What then, is the effect of this function? What does it change? Well it changes the 3 into a 9.

And nothing else.

So why is myFunction pure? There are two things that make it pure:

  • It has only one effect
  • It only affects its inputs

There are my rules for purity.

Now consider this function:

an impure function

Now it has a side effect because it affects something outside of itself — reading and writing to a database. If you look at it like this — it’s literally an effect on the side.

This is important: a consequence of the side effect is that the function’s output is now not predictable from its input alone — the output also depends on what is in the database and what it writes to that database.

This function now has two effects:

  • It changes a 3 to a 9
  • It writes to a database

It now violates both the rules — It has two effects, and it affects something which is not one of its inputs — (the database). So, clearly it is impure.

But what the side effect is doing is IO (Input/Output) — which is very useful! In fact if your program can’t take input or produce output it’s hard to imagine how it could be useful at all.

So what to do? Well you can try and minimise the use of side effects — a common approach — side effects become the programmers guilty secret. Programmers talk about isolating side effects — trying to push them to one place. Another approach is to use the IO monad — where you can do as much IO as you like and still be pure!

There are quite a few descriptions of IO out there so I am going to be brief. The basic idea is whenever you want to do something impure you wrap it in an IO monad.

val pureAndInnocent = IO { println("I'm a naughty side-effect!") }

What you have done is described the side effect — nothing actually happens until you call pureAndInnocent.run(). So pureAndInnocent is as the name suggests, pure - even if it describes something impure — it doesn’t actually do it. You might say: “hey — all you’re doing is just delaying the side-effect!” and you’d be right. But it works, trust me. That’s all I’m going to say for now. In my next post I am going to show you how to integrate the IO monad into a (fairly) realistic program by creating a purely functional API

--

--