Hacker News new | past | comments | ask | show | jobs | submit login

Yes, this is a real problem and I've been bitten by it more times than I can count. Now I always keep this handy website ready: https://doesitmutate.xyz/



TypeScript does a pretty good job here if you're willing to add a bit of extra syntax:

  const a = [1,2,3]
  a.push(4)

  const b: readonly number[] = [1,2,3]
  b.push(4) // Property 'push' does not exist on type 'readonly number[]'.


Well, Object.freeze in plain JS can help too.

    > Object.freeze([1,2,3]).push(4)
    TypeError: can't define array index property past the end of an array with non-writable length (firefox)
    Uncaught TypeError: Cannot add property 3, object is not extensible (chrome)
Of course, it will only blow up at runtime. But better than not blowing up at all, creating heisenbugs and such.

I often find myself writing classes where the last step of a constructor is to Object.freeze (or at least Object.seal) itself.


For what it's worth, there are only two, maybe three methods in that entire list that mutate where it's not obvious: sort, reverse, and (maybe) splice. All the other methods (like push, pop, fill, etc) are methods whose entire purpose is to mutate the array.


That was my first impression. But then the same logic applies to concat. ("I want to add another array").


Sometimes I don’t. Actually usually I don’t, I do a lot of [].concat(a, b).


Thanks for sharing.

I think this is the kind of thing you just have to learn when you use any language. But when you're switching between half a dozen, being able to rely on consistent founding design principles really makes things easier. And when there aren't any, this kind of guide helps.


I really like Python's design here, if we are not talking about full on language features to enforce immutability, where functions that mutate never return a value and are named with verbs (e.g. 'sort()'), while functions that don't mutate return their value and are named with adjectives (e.g. 'sorted()'). This feels natural - mutations are actions, while pure functions are descriptions.

The only real downside is the lack of return values mean you can't chain mutations, but personally that never bothered me.


i used to like that distinction as well but verbs are too useful to let mutating stuff use them all up! and pure functions are actions as well, they just result in a new thing. also, some verbs sound awkward adjectified: take, drop, show, go, get ...


That sounds pretty reasonable. I can see the case for mutation support, but the unpredictable nature of it is what is frustrating and dangerous.


Coming from PHP, we’re used to it. Half the methods have $haystack, $needle, and the other half use them in the other order.


I feel a better form for this site would be:

Mutates: push, pop, shift, unshift, splice, reverse, sort, copyWithin

Does Not Mutate: everything else




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: