What does" immutable " really mean?

In this question I asked about value types and reference types in C#, it was quoted in the accepted answer that instances of structs must be immutable objects. Reading in the wikipedia I confirmed that an immutable object should not have its state modified after it was created. But this is confusing, because after all, if I declare a variable either of a struct type or a class Type, I can modify its value at any time, or else it would be a constant.

Actually, int is a struct as far as I know, so in that case if I declare a variable of Type int it shouldn't be modified if instances of structs are actually immutable. But this is clearly not true, I can do int i = 1 and then i++ and only in this I have already changed its state.

So what does "immutable objects" really mean and how is this concept a useful concept in object orientation?

Author: Comunidade, 2014-05-11

3 answers

Variable X value

Values can be mutable or immutable, variables containing values are always, by definition, mutable. Variable refers to something that varies, that changes, that is changeable.

It is common for those who write about the subject to use a looser and not so academic language, which can lead to a misinterpretation even. You're right in doubt. It is rare who writes with all the specified details as correctly as possible in these cases. And that's what I did there in the question. That is why this new question is up. So if someone says "the variable x is immutable", read"the contents of the variable x is immutable".

Constants

Just like a constant, by definition, is immutable. I would like to say that the values of the constant are also always immutable. In C# they are, but some languages have managed to let a constant have the mutable value. It's a conceptual mistake that C# didn't make.

At least C# makes it clear that PI and MaxValue of type int are constants. Whereas MaxThreads and PercentualDeDesconto are readonly, that is, they do not change during the entire execution of an application instance, but can change from one execution to another, or from one version to another. There are some other differences that do not come to the case now.

Struct X Class

It is highly recommended that structs have their immutable values. This is in the C#documentation. It is very strange to have an object for value let it be changeable. Technically it is possible because may exist some situation that this is really useful and correct.

Classthey are usually changeable. But they don't have to be. The largest example is string which is a type by reference but has value semantics, that is, its value is immutable.

But how? I can change the value of a string. I can do:

var s = "teste";
s = "mudei";

There was a change in the value of the variable and not the value of the string. You don't changed the text, you created a new text and changed the reference (which is in the variable) to this new text.

Immutability example

See this struct:

struct Point {
    public float X;
    public float Y;
}

It is changeable. You shouldn't. Why?

You can change the value of X and Y independently. You are changing the value itself and not the variable. And a struct should not allow that.

Isn't it strange to change a part of the point without it being another point?

struct Point {
    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Already changes everything. The only way to change a value of the variable is to completely change the value contained in it. In this case you create a new value and allocate in the variable, you do not change the value allocated in it. Its use would be:

var p = new Point(2, 5);
// p.x = 7; seria um erro, você nem consegue acessar os membros individualmente.
p = new Point(7, 5);

Did you realize that you can't change just one member of the value? has to create a new value and associate that new value with the variable. This is immutability .

You change not only the value, you change the identity of it. Cartesian point 2.5 is different from point 7.5, it is not the same point with a different characteristic.

Note that adding public properties to access members x and y does not cause a problem. But if you allow assigning values to them, you fall into the same problem as the previous example of Point. Then you could create a property with only get.

Example of mutability

Now see this code:

struct Pessoa {
    public string nome; 
    public int idade;
    public Decimal salario;
    public DateTime CadastradaEm;
}

public class Exemplo {
    static void Main() {
        Pessoa p;
        p.nome = "João";
        p.idade = 18;
        Console.WriteLine("{0} tem {1} anos", p.nome, p.idade);
       
        p.idade = 20;
        Console.WriteLine("{0} tem {1} anos", p.nome, p.idade);
    }
}

Another problem

Leaving aside that this is exposing fields to external direct access (it's just a simplified example, I don't need to follow such "good practices" here), what's the problem with this code?

If this is a struct it should be immutable but this is not the error. The way it is, it is clearly a changeable object, you can change the members individually. No problem. That's probably what you want in this case.

If this structure has multiple fields, it becomes very large. Large objects do not look good on a struct. Finally struct s are copied by value. Copies of large objects are inefficient. So we already have two reasons, inefficiency and mutability to say that this should be a class. The error was to set this structure to struct instead of class. More details in this question .

Identity

In this example above despite changing the age of the person, the person is the same, the identity of the object is the same, so the object is changeable. Object characteristics can be changed without the object becoming something else. Even if you change the name from "John" to "Mary" (very common nowadays:)) it would still be the same person. A name can be changed by several factors, such as typo or change of marital status, just to name the most common.

When you use the code:

var i = 0;
i = 5;

Semantically is the same as saying:

var i = new Int32(0);
i = new Int32(5);

Int32 it is such struct that equals int. Note that each change in the value, you are creating a new object, with equivalent identity. By chance it is being "saved" in the same place, it is replacing the previous value, but not only the variable has changed, but its value as a whole has changed.

Then in the example:

int i = 0;
i++;

Is the same as:

int i = default(Int32); //só para mostrar outra forma de interpretar a mesma coisa
i = new Int32(i + 1);

Does not mean that the compiler interprets it exactly like that, but it is a way that helps to understand.

Note that the value of i is being changed as a whole, as per the definition I gave above.

Conclusion

Seems strange at first glance, but if you look at the variable itself and its value as distinct things it becomes easy to understand that the value never changes, it is exchanged for another.

The easiest way to understand immutability is to look at whether the change can occur in parts of the object (fields, properties, elements of a array , etc.) or if it can occur only in its whole.

Immutability does not need to fit any definition strict object orientation. It is a concept applied to any paradigm.

The subject is quite vast and is something that few understand correctly. I think I do not understand everything correctly. But here already has an important part about it.

More info (The question is about Java, but the idea is the same).

Exercise

Answer if a phone that has the DDD (area code) and the number itself, can exchange your DDD and stay with it identity? And can he switch carriers and keep his identity?

If you create a variable (of type) int with value 0 and then assign the value 0 in it, did it change the identity?

answers in the comment below

I put on GitHub for future reference.

 66
Author: Maniero, 2020-09-02 14:51:56

The big question that is confusing to you is about what is an object.

Object, physically speaking, is an allocated space in memory to keep your reference and use it in your code you need a variable that references it. So realize that there is a difference between object that does not change and variable that does not change.

A variable that does not change would be a constant, at the moment you assign an object to it you can no longer change from object.

An object that does not change is an immutable object, you cannot change its attributes after first initialized, however you can at any time create a new object and assign it to the same variable that referenced the old one.

When you do i++ you are creating a new object incremented from one of the previous object and assigning that new object the same variable i.


sorry I do not delve much, but I do not know the C# syntaxes, I know Java where the concept is the same.

 25
Author: Math, 2017-11-14 23:16:30

I wrote an article about this ( https://epxx.co/artigos/imutavel.html). the basic idea is this: in some languages, there is no distinction between "value of" and "reference to" an object. For example, in Java an object variable always contains a reference. Ditto Delphi, Ditto Python... Suppose 5 variables contain the same object of Type A:

a = new A("bla"); b = a; c = b; d = c; e = d;

If the object is changed via any variable, all 5 variables are affected, because they all contain references to the same object.

For some classes, it makes more sense to behave as a primitive type, such as integer or string. For example, if I do

a = 100; b = a; c = b; d = c; e = d;

I really expect that by doing b = 200, the other variables remain with the value 100, right? Ditto if it were a string; when we assign one string variable to another, what we want is actually a copy of the original string, not two variables pointing to it string.

Constructing the class to be immutable after construction allows your objects to simulate this behavior of primitive types. For example, in Java The String is an immutable class. When I do

a = "bla"; b = a; c = b;

It is true that at first the three variables refer to the same String object. However, since it is an immutable object, the only way to change the value of a variable is to assign it another completely new String. All methods of manipulation of Strings return new Strings, never mess with the original.

Under the hood, string classes use various tricks to improve their performance, but always maintaining the appearance of immutability. For example, if we do

A = "bla"; a + = "ble";

It may be that the String implementation checks how many references there are to the "bla"object. If there is only one, then concatenation of "bla" and " ble " can modify the original String. If there are two or more references (b, c...), copy-on-write, i.e. create a new string "blable" only for the variable "a".

 2
Author: epx, 2018-04-05 05:22:24