DEV Community

Washing your code: avoid mutation

Artem Sapegin on March 25, 2020

You’re reading an excerpt of my upcoming book on clean code, “Washing your code: write once, read seven times.” Preorder it on Leanpub or read a ...
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!