Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
May 15, 2020 Issues with immutable/inout | ||||
---|---|---|---|---|
| ||||
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? |
May 15, 2020 Re: Issues with immutable/inout | ||||
---|---|---|---|---|
| ||||
Posted in reply to burt | On 15.05.20 12:13, burt wrote: > Hello, > > Since D's const, immutable and inout are transitive, it is more difficult to write const-correct code. There's no such thing. This is a C++-ism. > ... > > 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. > ... `inout` is supposed to work. I think this is a regression. Not sure when it happened but it was between 2.060 and 2.070.1. > 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 agree. One way to make some progress on this would be to give special semantics to `immutable`/`shared`/... classes. (I.e., enable conversion between references of different mutabilities.) > 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? > Mark the constructors `pure` and it will work. |
May 15, 2020 Re: Issues with immutable/inout | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Friday, 15 May 2020 at 11:08:36 UTC, Timon Gehr wrote: > On 15.05.20 12:13, burt wrote: >> Hello, >> >> Since D's const, immutable and inout are transitive, it is more difficult to write const-correct code. > > There's no such thing. This is a C++-ism. Oh, I did not know that. I assumed it referred to marking the right things const to signal it won't or shouldn't mutate. >> ... >> >> 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. >> ... > > `inout` is supposed to work. I think this is a regression. Not sure when it happened but it was between 2.060 and 2.070.1. According to run.dlang.io, it stopped working in 2.063. I'm guessing it was caused by https://dlang.org/changelog/2.063.html#ctorqualifier. I can't really find out what PR caused it though. > ... > Mark the constructors `pure` and it will work. Thanks, but this appears to only work with non-reference types: ``` //Compared to this: //alias T = int; alias T = char[]; class B { T x; this(inout T x) inout pure { this.x = x; } } void main() {} unittest { auto b = new immutable B(T.init); } ``` (Compile with -unittest) |
May 15, 2020 Re: Issues with immutable/inout | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Friday, 15 May 2020 at 11:08:36 UTC, Timon Gehr wrote:
> On 15.05.20 12:13, burt wrote:
>> Hello,
>>
>> Since D's const, immutable and inout are transitive, it is more difficult to write const-correct code.
>
> There's no such thing. This is a C++-ism.
In D I just take it to mean "usable with const or immutable instances". It's a shame (to me at least!) that the default is a mutable `this`.
|
May 15, 2020 Re: Issues with immutable/inout | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves | On Friday, 15 May 2020 at 14:38:54 UTC, Atila Neves wrote:
> On Friday, 15 May 2020 at 11:08:36 UTC, Timon Gehr wrote:
>> On 15.05.20 12:13, burt wrote:
>>> Hello,
>>>
>>> Since D's const, immutable and inout are transitive, it is more difficult to write const-correct code.
>>
>> There's no such thing. This is a C++-ism.
>
> In D I just take it to mean "usable with const or immutable instances". It's a shame (to me at least!) that the default is a mutable `this`.
Yes, a preview flag to change the defaults would be very much appreciated!
Though I guess a pragma or similar to change the shameful defaults on a per package-basis would even be better ;-)
|
Copyright © 1999-2021 by the D Language Foundation