Say you have a variable:
var x = [1,2]
If it is a mutable object, you could do:
x.append(3)
x
>> [1,2,3]
But if it is immutable, and you wanted to change the value of x, you would effectively have to do:
// init x
var x = [1,2]
// add a 3 to x
x = [1,2,3]
x
>> [1,2,3]
What's the difference between mutability and just changing the variable?
My best guess is that when you do append(3)
it is modifying a reference to the same variable in memory, but when you x = [1,2,3]
, you possibly declaring a new variable x, referencing a new block in memory, and deallocating the old block that x=[1,2]
occupied.
It seems like immutable variables should not be able to change. But many times we want immutable variables to change. For example, in React, state variables are considered immutable. But the point of having state is so that the variables can change. So to change the values of them you need to go through these very roundabout ways, like calling setState()
, and feeding it callback functions if you want to do something like append an element to a list.
There are variables and there are values. Variables are like names or addresses by which we refer to values. Mutability applies to values, not variables.
A mutable value can be changed in-place without creating a new value. For instance, if I create an integer value and assign it the value of one, I can then increment that value without allocating space for a new integer; the value is incremented in-place. Any references to that value will all immediately see the change because they are referring to the one value that has now been changed - or mutated.
Immutable values cannot be changed in-place. Suppose strings are immutable in our language. If I create a string and initialize it to the value "hello world", it is not possible to change that value without creating space for a new string. If I want to change the value to "goodbye world", I must create a new string value with newly allocated memory. Any variables that referred to the original value will continue to do so unless they are updated to refer to the new value.
Constancy is a similar concept that applies to variables and has to do with whether the thing being referenced by the variable is allowed to change. This gets muddied a bit with primitive types; really, a const int variable should be incrementable since incrementing the int doesn't change the memory being referred to, just the stuff inside that memory. However, constant/readonly lists can typically be added to and removed from without issue, for instance, so the distinction between constancy (of variable reference) and immutability (of value) is a little more well-preserved there.