DEV Community

Cover image for You Need to Know About Pure Functions & Impure Functions in JavaScript

You Need to Know About Pure Functions & Impure Functions in JavaScript

Code of Relevancy on March 28, 2023

With this article, we will explore what pure/impure functions are and their differences in JavaScript. Let's dive in.. What is a funct...
Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

Interestingly, due to the way JS works, it is possible that this function:

function add(a, b) {
  return a + b;
}
Enter fullscreen mode Exit fullscreen mode

could cause side effects, and even return a different value each time it's called - even with the same inputs. It all depends upon what a and b are. So, in a VERY strict sense it can be argued that it isn't pure. I'll explain further if you don't know what I'm getting at.

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

Different values each time:

const a = 1 // a number
const b = { valueOf: () => performance.now() } // an object with a method

// Pure function?
function add(a, b) {
  return a + b
}

console.log(add(a, b))  // 22279
console.log(add(a, b))  // 49558 - same inputs, different result
Enter fullscreen mode Exit fullscreen mode

Side effects:

const a = 1  // a number
const b = { valueOf () { console.log('Hello world'); return 2; } }  // Object with method

// Pure function?
function add(a, b) {
  return a + b
}

console.log(add(a, b))  // 'Hello world' (side effect) then 3
Enter fullscreen mode Exit fullscreen mode
Collapse
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

Well on the first example, the inputs are not the same in both executions, because performance.now() returns a value, hence you are calling add(1, 22278); the first time and add(1, 49557); the second one. By that means add is still a pure function in the first example.

I get your point on the other one and there are tones of nuances into this topic, in this specific use-case TS helps a lot:

const a = 1  // a number
const b = { valueOf () { console.log('Hello world'); return(2); } }  // Object with method

// Pure function
function add(n1: number, n2: number) {
  return a + b
}

console.log(add(a, b)) // TypeError, Object !== number
Enter fullscreen mode Exit fullscreen mode

So you end up with fine tuned control on how the given function is used. Of course you can still do dynamic stuff and trick everything in runtime but still you need to explicitly put effort into breaking it most of the time (specially if the types are well defined everywhere).

Best regards

Thread Thread
 
jonrandy profile image
Jon Randy 🎖️ • Edited

...hence you are calling add(1, 22278); the first time and add(1, 49557); the second one...

Not at all, the inputs are identical each time. The second of which is an object, with an unchanged method. Nothing about the input to the add function has changed on the second call. JS itself will call the valueOf function during coercion - after it has been passed in.

Thread Thread
 
joelbonetr profile image
JoelBonetR 🥇

We both know each other from the community and I'm pretty sure you understand that abstracting an impure function such performance.now() doesn't avoid getting different values each time you call it (to a precision of 5 milliseconds in this case). I don't have time right now to discuss with troll statements to stress it further (even though you know I like it a lot)

The usage of valueOf in the example is pretty neat, though 😂

Thread Thread
 
jonrandy profile image
Jon Randy 🎖️ • Edited

You've misunderstood the code. I was just pointing out that the inputs to add on both calls are the same. I'm actually curious if it would be possible to write a 'true' pure function in JS that would take into account all the coercion quirks 🤔

Collapse
 
abhixsh profile image
Abishek Haththakage

valuable article

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thanks for your feedback bro

Collapse
 
Sloan, the sloth mascot
Comment deleted
 
Sloan, the sloth mascot
Comment deleted
 
Sloan, the sloth mascot
Comment deleted
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
ant_f_dev profile image
Anthony Fung

This is a great walkthrough of pure functions.

This might not apply to JS but in some languages, e.g. C#, it's possible to change the next line that gets run in the debugger. Pure functions are great because of their idempotence (i.e. the same inputs give the same outputs, as mentioned in the article), meaning that they can be run over and over if necessary during the debugging process to understand what's going on.

By they way, how did you create the cool animated graphics?

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you my friend for bringing up an interesting point of pure functions with debugging.. BTW I use canva.com to create animated graphics..

Collapse
 
abhixsh profile image
Abishek Haththakage

Interseting article

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you bro

Collapse
 
fruntend profile image
fruntend

Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 👍

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thanks a ton man

Collapse
 
phi1ipp profile image
Philipp Grigoryev

One more benefit of pure functions - they can be memoized, b/c of their nature to produce the same result for the same arguments

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Make sense. Thank you for sharing your thoughts

Collapse
 
jermaynehudson34465 profile image
Jermayne Hudson

Interesting, thx!

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you boss