Pure Functions in Javascript

ยท

4 min read

Pure Functions in Javascript

If you are a Javascript developer, chances are you have come across the term "Pure Functions". So, what exactly is a pure function?

Pure functions are the foundation of functional programming. For a function to be pure it must follow the rules below:

  • Pure functions must be predictable
  • It should not perform any side effects

Pure functions must be predictable

Now, what does this mean exactly?

And by 'this' I am not talking about the keyword 'this'. To this day, I still cannot define 'this'

๐Ÿ˜ฌ

What does a function exactly do?

  • Take an input
  • Process it
  • Give an output

Pure function takes at least one argument, processes it, and always returns the same output.

Let's see an example

const square = num => num * num;

console.log(square(5));  //25

In this example above, no matter how many times, the output would always be the same if you pass the same number.

let five = 5;
const incrementByFive = (num) => five+= num;

console.log(incrementByFive(5));  // 10

console.log(incrementByFive(5));  // 15

In the example above, our function depends on a global variable and mutates it. This gives us different output every time, even though we pass the same number.

This is why pure functions are predictive so that we can reuse them anywhere knowing what the output will be.

If your function is dependent on global variables then it is not a pure function. A pure function should return a value, based only on its arguments.

Pure function should not perform any side effects

Now, what are side effects?

Batman thinking gif

Side effect includes DOM manipulation, data fetching, mutating functional arguments, etc.

Pure functions are meant to be reusable. If one of these functions starts DOM manipulation or data fetching then it will do it everywhere it is used.

What exactly do mutating functional arguments mean? Consider an empty cart array and a product object which needs to be added to the cart. Let's write a function to add items to this cart.

const cart = [];

const product = {
  name: 'Headphone',
  price: 2000
}

const addToCart = (cart, productToBeAdded) => {
   cart.push(productToBeAdded);
  return cart;
}

const newCart = addToCart(cart, product);

console.log(newCart);  // [{name: 'Headphone', price: 2000}]

Great! Now we have a newCart array in which we added our product. But is the original cart array still the same? Let's see ...

console.log(cart);  // [{name: 'Headphone', price: 2000}]

But we stored the value from the function in newCart. Then why does this happen? Array.push is a destructive method. When used it will mutate the existing array.

It is not a good practice to mutate an existing array. Why? Other functions may be using the cart array, but now that we mutate it we have to worry about how it will affect the output of the other function in which it is being used.

Now that we know what mutating an argument means, how can we avoid it? We simply use the Spread syntax (...) which lets you copy all the existing elements on an array or object.

const cart = [];

const product = {
  name: 'Headphone',
  price: 2000
}

const addToCart = (cart, productToBeAdded) => {
   return [...cart, productToBeAdded];
}

const newCart = addToCart(cart, product);

console.log(newCart)  // [{name: 'Headphone', price: 2000}]

console.log(cart)  // []

You can also overwrite existing values in an array or object using the spread syntax without mutating the original array or object.

Conclusion

Pure functions are simple reusable functions that take at least one argument, processes it, and give an output.

Pure functions should always return a value or other function.

Pure functions should not have any side effects.

Does this mean you should only use pure functions in your application? Of course not, we always need impure functions to run our side effects.

That's all folks gif

Thank you for reading till the end ๐Ÿ˜„ Let me know in the comments if you like the blog or if you have any suggestions!

ย