mutable, const, immutable guidelines

Ali Çehreli acehreli at yahoo.com
Tue Oct 8 21:31:54 PDT 2013


On 10/08/2013 03:12 PM, qznc wrote:

 > On Monday, 7 October 2013 at 17:57:11 UTC, Ali Çehreli wrote:
 >> To look at just one usage example, the following line carries two
 >> requirements:
 >>
 >>     auto a = T();
 >>     immutable b = a;
 >>
 >> 1) b will be an immutable copy of a.
 >>
 >> 2) T will always be usable as in that fashion.
 >>
 >> If T appears on an API, it is the responibility of the user to ensure
 >> whether they are allowed to treat T in that way. Otherwise, they risk
 >> maintainability if the module decides to change T in any way that fits
 >> the module's needs. If they have not yet advertised that T can be used
 >> as immutable, it should not be.
 >
 > I do not agree with you, that the user has the responsibility.

I have difficulty agreeing with myself as well. :) However, the power of 
immutable makes me think so. Interestingly, once a user creates an 
immutable variable of a type, that type must support that use.

 > Rather I
 > think the provider of T has the responsibility to maintain backwards
 > compatibility.

Agreed but I don't know how. Here is challenge: Let's start with the 
following program:

// Library type
struct MyInt
{
     int i;
}

void main()
{
     // User code
     auto a = MyInt(1);
     immutable b = a;
}

Let's assume that the library adds a private dynamic array of ints to 
that type:

// Library type
struct MyInt
{
     int i;
     private int[] history;    // <-- Added
}

void main()
{
     // User code
     auto a = MyInt(1);
     immutable b = a;          // <-- Existing code breaks
}

Error: cannot implicitly convert expression (a) of type MyInt to 
immutable(MyInt)

Apparently, the library made a change that made its type 
non-immutable-able. :p What is missing in MyInt? How should it be 
defined instead of simply adding 'history'?

 > My principle is "anything is allowed, unless explicitly
 > forbidden". This includes immutable type constructing. It is great that
 > we get a type error, if backwards compatibility is broken.

Agreed. What is the solution?

 > Nevertheless, the question of responsibility seems to be subjective. Are
 > there any clear technical reasons for either way?

Technically, MyInt is in a breaking state because the user used it as 
immutable. One way to look at this situation is to observe that the user 
took some freedom of the library just by using its type as immutable.

 > Unfortunately, there is no way for the provider to allow or disallow
 > immutable(T). Maybe there should be a UDA or something for this?

I think the language is lacking tools to support the use case above.

Ali



More information about the Digitalmars-d-learn mailing list