←back to thread

498 points azhenley | 2 comments | | HN request time: 0.001s | source
Show context
EastLondonCoder ◴[] No.45770007[source]
After a 2 year Clojure stint I find it very hard to explain the clarity that comes with immutability for programmers used to trigger effects with a mutation.

I think it may be one of those things you have to see in order to understand.

replies(17): >>45770035 #>>45770426 #>>45770485 #>>45770884 #>>45770924 #>>45771438 #>>45771558 #>>45771722 #>>45772048 #>>45772446 #>>45773479 #>>45775905 #>>45777189 #>>45779458 #>>45780612 #>>45780778 #>>45781186 #
rendaw ◴[] No.45770924[source]
I think the explanation is: When you mutate variables it implicitly creates an ordering dependency - later uses of the variable rely on previous mutations. However, this is an implicit dependency that isn't modeled by the language so reordering won't cause any errors.

With a very basic concrete example:

x = 7

x = x + 3

x = x / 2

Vs

x = 7

x1 = x + 3

x2 = x1 / 2

Reordering the first will have no error, but you'll get the wrong result. The second will produce an error if you try to reorder the statements.

Another way to look at it is that in the first example, the 3rd calculation doesn't have "x" as a dependency but rather "x in the state where addition has already been completed" (i.e. it's 3 different x's that all share the same name). Doing single assignment is just making this explicit.

replies(10): >>45770972 #>>45771110 #>>45771163 #>>45771234 #>>45771937 #>>45772126 #>>45773250 #>>45776504 #>>45777296 #>>45778328 #
skeezyjefferson ◴[] No.45771110[source]
whats the difference between immutable and constant, which has been in use far longer? why are you calling it mutable?
replies(4): >>45771178 #>>45771248 #>>45773965 #>>45774112 #
Thorrez ◴[] No.45771178[source]
Immutable and constant are the same. rendaw didn't use the word mutable. One reason someone might use the word "mutable" is that it's a succinct way of expressing an idea. Alternative ways of expressing the same idea are longer words (changeable, non-constant).
replies(3): >>45771258 #>>45771300 #>>45773072 #
a4isms ◴[] No.45771300{3}[source]
In languages like JavaScript, immutable and constant may be theoretically the same thing, but in practice "const" means a variable cannot be reassigned, while "immutable" means a value cannot be mutated in place.

They are very, very different semantically, because const is always local. Declaring something const has no effect on what happens with the value bound to a const variable anywhere else in the program. Whereas, immutability is a global property: An immutable array, for example, can be passed around and it will always be immutable.

JS has always hade 'freeze' as a kind of runtime immutability, and tooling like TS can provide for readonly types that provide immutability guarantees at compile time.

replies(1): >>45772243 #
everforward ◴[] No.45772243{4}[source]
Arrays are a very notable example here. You can append to a const array in JS and TS, even in the same scope it was declared const.

That’s always felt very odd to me.

replies(4): >>45773093 #>>45773609 #>>45779719 #>>45781098 #
1. a4isms ◴[] No.45781098{5}[source]
There is no exception for ANY data structure that includes references to other data structures or primitives. Not only can you add or remove elements from an array, you can change them in place.

A const variable that refers to an array is a const variable. The array is still mutable. That's not an exception, its also how a plain-old JavaScript object works: You can add and remove properties at will. You can change its prototype to point to something else and completely change its inheritance chain. And it could be a const variable to an unfrozen POJO all along.

That is not an exception to how things work, its how every reference works.

replies(1): >>45785602 #
2. everforward ◴[] No.45785602[source]
I know, and I do agree it's consistent, but then it doesn't make any sense to me as a keyword in a language where non-primitives are always by-reference.

You can't mutate the reference, but you _can_ copy the values from one array into the data under an immutable reference, so const doesn't prevent basically any of the things you'd want to prevent.

The distinction makes way more sense to me in languages that let you pass by value. Passing a const array says don't change the data, passing a const reference says change the data but keep the reference the same.