Skip to main content

Command Palette

Search for a command to run...

Understanding pure functions in javascript

Published
•3 min read•View as Markdown
Understanding pure functions in javascript

Pure functions allow us to get a predictable result every time they are been invoked. They find its applications in redux, functional programming. Hence in order for a function to be classified as pure, it must fulfill certain rules:

1) Given the same arguments, it returns the same result: let us illustrate this

const sum = (a, b) => a + b 
sum(1, 3) // 4
sum(1, 3) // 4
sum(4, 2) // 6
sum(4, 2) // 6

looking at sum produces the same result, when we pass the same argument to it, sum satisfies the first rule of pure function.

2) Pure function does not produce side effects:- sides effects could be mutating external state, logging(e.g console.log), API request, I/O operations.

const sumWithLog = (a, b) => {
console.log(a, b)
return a+b
}

const arr = [2, 3, 4];
const addToArr = (arr, a) => { 
arr.push(a);
return arr;
}
console.log(addToArr(arr, 5)) // [2, 3, 4, 5];
console.log(addToArr(arr, 5)) // [2, 3, 4, 5, 5];

Looking at sumWithLog it technically violates the second rule by definition despite it obeys the first rule, while addToArr is not also a pure function because it's mutating external state. let's make impure addToArr to become pure by adjusting the code,

const arr = [2, 3, 4];
const addToArr = (arr, a) => {
const arrCopy = [...arr]  //  line 1
arrCopy.push(a);
return arrCopy;
}
console.log(arr) // [2, 3, 4] 
console.log(addToArr(arr, 5)) // [2, 3, 4, 5];
console.log(addToArr(arr, 5)) // [2, 3, 4, 5]
console.log(arr) // [2, 3, 4]

Looking at the code snippet above, addToArr obeys our first rule and second rule, our result is now predictable. At line 1 we make a copy of arr by spreading arr elements which gave us the capability to not mutate the original arr. it's also important to note that spread operator does shallow copying of values.

3) Pure functions depends only on the arguments passed to them. What this actually means is a pure function is self-contained, it does not depend on values outside its scope to determine its final value. let's illustrate this:

const b = 6
const sum1 = (a) => (a + b) //  line 1 
const sum2 =  (a, b = 1) => (a + b) line // 2

sum1 is considered an impure function because it takes value outside its scope to determine the final result which could be changed. The value of b in sum1 could easily be changed by external code which makes the function to unpredictable. sum2 corrects the defect in sum1.

Hence for a function to consider a pure function, the three rules above must all be satisfied, violation of any automatically makes the function impure. Finally, pure functions make our code more predictable and testable.

D

Good article, though watch your formatting, your code is entirely devoid of any indentation in the array example, and is very hard to follow. Also, you almost have it, but you still return to use "push" to add to the new array, which means it's mutating the arrCopy

const addToArr = (arr, a) => {
  const arrCopy = [...arr]  //  line 1
  arrCopy.push(a); // <-- mutates arrCopy
  return arrCopy;
}

This could be far more succinct and reman pure with:

const addToArr = (arr, a) => [...arr, a]
R

Thank you for the feedback, I will work on the indentation for clarity. Despite arrCopy.push(a) mutating arrCopy, I think it still does not violate the predictability of that function.