mutable, const, immutable guidelines

qznc qznc at web.de
Thu Oct 10 16:06:18 PDT 2013


On Wednesday, 9 October 2013 at 04:31:55 UTC, Ali Çehreli wrote:
> 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)

Maybe the fact that D allows this implicit copy to immutable is 
the problem? If one could require the use of a specific function, 
this function could be overridden with working behavior. The 
following code works.

import std.exception: assumeUnique;

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

// idup for creating immutable MyInts
immutable(MyInt) idup(const MyInt mi) pure nothrow @trusted {
   MyInt cpy = MyInt(mi.i);
   return cast(immutable) cpy;
}

// special version for performance
immutable(MyInt) idup(immutable MyInt mi) pure nothrow @trusted {
   return mi;
}

unittest {
   auto a = MyInt(1);
   immutable b = a.idup;     // <-- Code does not break
}

D could either remove the implicit-copy-to-immutable or provide a 
special copy-constructor for immutable structs.


More information about the Digitalmars-d-learn mailing list