DEV Community

Washing your code: avoid mutation

Artem Sapegin on March 25, 2020

You’re reading an excerpt from my book on clean code, “Washing your code.” Available as PDF, EPUB, and as a paperback and Kindle edition. Get you...
Collapse
 
lexlohr profile image
Alex Lohr

While Immutability can make it easier to reason about your code and avoid errors when using reference comparison, it can also come with a hefty performance cost that may as well turn it into an anti-pattern.

Consider the following code:

largeArray.reduce((pairs, item, index) =>
  index % 2 == 0
  ? [...pairs, item]
  : [...pairs.slice(0, pairs.length - 2), [pairs.at(-1), item]],
  []
);
Enter fullscreen mode Exit fullscreen mode

Multiple arrays are created on every iteration. Contrast it with the following:

largeArray.reduce((pairs, item, index) => {
  if (index % 2 == 0) { pairs.push([item]); }
  else { pairs.at(-1).push(item); }
  return pairs;
}, []);
Enter fullscreen mode Exit fullscreen mode

The latter is significantly faster.

Collapse
 
sapegin profile image
Artem Sapegin

Hey Alex, great point! And I mention performance in the newer version of this post: blog.sapegin.me/all/avoid-mutation/

Collapse
 
lexlohr profile image
Alex Lohr • Edited

I think this could be a bit more nuanced. I like that you make clear that you should never mutate values without making it obvious. I still think that immutability as a pattern is somewhat overrated, especially in narrow scopes.

As a beginner, avoiding mutation makes sense. Once you become more advanced, you can reason about why to use mutations in certain cases. Though I definitely agree that mutating arguments is an anti-pattern.

Also, you should consider not using arrays at all if you don't explicitly need them; iterators and generators might be a better choice in some cases.

Thread Thread
 
sapegin profile image
Artem Sapegin

I agree that immutability is not a pattern, and I'd much prefer to have a language that's immutable by default, so you don't have to think about it. And I like the idea about the scope.

I think the main problem with mutation is that the problems caused by mutation are often very tricky to debug. Mutation of a function parameter, even if it's a very small function, could cause problems very far from this function.

Collapse
 
salz150 profile image
Chris Salisbury

Lots of great ideas! Thanks for sharing!