getting rid of immutable (or const)

Ali Çehreli acehreli at yahoo.com
Thu Sep 5 21:22:12 UTC 2019


On 09/05/2019 12:51 PM, berni wrote:

 >>     int[int] a;
 >>
 >>     immutable int b = 17;
 >>     a[1] = b;                          // <-- expecting error here

As explained elsewhere, a[1] is a mutable int. That assignment is 
copying b on top of the element.

 >>     const oldPointer = (1 in a);
 >>     immutable int c = 10;
 >>     a[1] = c;
 >>     assert(oldPointer is (1 in a));
 >>
 >>     Point[int] d;
 >>
 >>     immutable Point e = Point(17);
 >>     d[1] = e;                           // <-- but error is here

That is the equivalent of

   d[1].x = e.x;

It can't work because the left-hand side is immutable. (immutable or 
const members make objects of those types unassignable.)

 >> const or immutable members make structs unassignable.
 >
 > But why? Here:

Otherwise the immutability guarantees woul be violated.

I understand your questioning the AA design but at the lowest level it's 
just assignment operation. I understand that it could be "emplacement" 
on top of the existing element but the guarantees would be violated even 
then because the 'in' operator returns a pointer. Placing a new object 
on the same address would make existing pointer-holders unhappy.

 > I understand, that I cannot change f[0], because it's allready got a
 > default value and that value would be overwritten. But in an aa, that
 > member does not exist before putting the Point in there, hence there is
 > nothing, that could be overwritten...

Yeah, it's highly likely just assignment on a default-valued object.

 >> Whether the members of a type are const or immutable should not be
 >> dictated by where the objects of that type will be used. If it makes
 >> sense otherwise, sure...
 >
 > I'm not sure if I understand that right. It's sort of an advice on how
 > to decide if one want's to make a member immutable or not, is it?

If it makes for the type to have immutable (or const) members, then 
fine; with the understanding that objects of that type cannot be 
assigned or mutated any other way, we can define them like that. What I 
meant is, because we want to use such a type in an AA and we don't want 
the element to change should not dictate the type's members. Using in an 
AA should be yet another usage of the type.

 > if immutable were that useless, why would it exist
 > at all?

immutable is useful: You can have immutable objects, immutable AAs 
(different from what we are discussing here), etc.

You can use immutable at a different level: not members but their 
members can be immutable. For example, a 'string' member would not be 
immutable itself but its chars would be immutable. There is no problem 
in having an AA with types having such a member:

struct Person {
   string name;
}

You can assign to Person objects but their names are immutable. If you 
wanted a Person where the name should never change, then you could make 
a const(Person), immutable(Person), or provide read-only access to 
'name', etc.

 > So I would like to understand, what's happening; being able to
 > predict, what works and what not. At the moment it's almost always the
 > opposite of what I think it should be...

As a general rule, I never make members const or immutable; this is a 
guideline that I carried over from C++. A recent issue I had with const 
members in C++ has been silent skipping of move assignment of objects. 
Unless one uses functional programming style, that's how it should be in 
D as well. Otherwise, assignment is disabled and AAs don't work as 
expected because they use assignment under the hood as well.

Ali



More information about the Digitalmars-d-learn mailing list