Issues with immutable/inout

burt invalid_email_address at cab.abc
Fri May 15 10:13:12 UTC 2020


Hello,

Since D's const, immutable and inout are transitive, it is more 
difficult to write const-correct code. Recently I tried writing a 
library with `immutable` in mind, but I feel like mutable and 
immutable cannot be mixed: you can only choose one.

The reason I think this is a couple of issues. The following code 
demonstrates the problem:

```
import std;

abstract class Base
{
     immutable int i;

     this(int i) @safe /*inout? (1)*/
     {
         this.i = i;
     }

     void update() @safe /*mutable*/;
}

final class SingletonDerived : Base
{
     static immutable SingletonDerived instance;
     shared static this() /*@safe*/
     {
         // I want this:
         //instance = new immutable SingletonDerived(42);
         // or this:
         //instance = new SingletonDerived(42);

         // but I have to use this, which is not @safe:
         instance = cast(immutable) new SingletonDerived(42);
     }

     override void update() @safe const
     {
         //nothing
     }

private:
     this(int i) @safe /*inout? (1)*/
     {
         super(i);
     }
}

void func(Base object) @safe
{
     object.update();
}

@safe unittest
{
     // cast is not @safe, and I would rather use @system only 
where necessary (2)
     auto object = (() @trusted => cast() 
SingletonDerived.instance)();
     assert(object !is null);
     func(object);
}
``` (compile with -main -unittest)

Problem (1): class constructors cannot be called with different 
mutabilities. When marking the constructor as mutable, you cannot 
create immutable objects; when marking as inout or immutable, it 
doesn't work either.

Problem (2): cannot (implicitly/safely) convert between immutable 
and mutable objects, even if the class is final and contains only 
immutable fields. It is bad that immutable applies to the class 
reference, and not to the underlying object.

I feel like D would be a lot more usable for me if these two 
issues were fixed. However, fixing problem 2 probably requires a 
change in the spec and in the language. Does such a change 
require a DIP or is a bug report enough? Or is there a different 
(@safe) solution that I overlooked?



More information about the Digitalmars-d mailing list