Pure functions are fundamental to functional programming, concurrency, writing testable code, and having deterministic determinable code. A function is only pure if, given the same input, it will always produce the same output.

Functions are used in 3 major ways:

  1. Mapping: Map input values to output values
  2. Procedures: Perform a sequence of steps
  3. I/O: Communicate with other parts of the system such as the screen, storage, system logs, or network

Pure Functions

Pure functions have two features:

  • given the same input, will always return the same output
  • produce no side effects

A simple way to know if a function is impure is if it makes sense to call it without using its return value. For pure functions, that is never the case.

Here’s an example of a pure function. Note that if it had side effects such as saving the value to disk or logging to the console, it wouldn’t still be pure.

// pure function
const double = x => x * 2;

Pure functions are completely independent of outside state which makes them immune to many bugs related to mutable state. They are also good for parallel processing across many CPUs or even distributed computing clusters, which makes them essential for many types of scientific and resource-intensive computing tasks.

Referential transparency

The idea is that an expression in a program may be replaced by its value (or anything having the same value) without changing the result of the program. This implies that methods should always return the same value for a given argument without having any other side effect.

Example in mathematics:

x = 2 + (3 * 4)

We can replace (3 * 4) with any other expression with the same value without changing the result of x. So:

x = 2 + 12
x = 14


Since programs are composed of subprograms, a method can be referentially transparent if a call to this method may be replaced by its return value.

function add(a, b) {
  return a + b;

function mul(a, b) {
  return a * b;

let x = add(2, mul(3, 4));

In this example mul method is referentially transparent because any call to it may be replaced with the corresponding return value. None of these replacement will change the result of the program.

// examples
let x = add(2, 12);
let x = 14;

Want to improve your JavaScript? I have a list of recommended JavaScript books.