On Wednesday, June 13, 2018 07:35:25 RazvanN via Digitalmars-d-learn wrote: > Hello, > > I'm having a hard time understanding whether this inconsistency > is a bug or intended behavior: > > immutable class Foo {} > immutable struct Bar {} > > void main() > { > import std.stdio : writeln; > Foo a; > Bar b; > > writeln("typeof(a): ", typeof(a).stringof); > writeln("typeof(b): ", typeof(b).stringof); > } > > prints: > > typeof(Foo): Foo > typeof(Bar): immutable(Bar) > > > It seems like the class storage class is not taken into account > which leads to some awkward situations like: > > immutable class Foo > { > this() {} > } > > void main() > { > Foo a = new Foo(); // error: immutable method `this` is not > callable using a > // mutable object > } > > To make it work I have to add immutable to both sides of the > expression : immutable Foo a = new immutable Foo(); this is a > wonder of redundancy. I already declared the class as immutable > so it shouldn't be possible to have mutable instances of it (and > it isn't), however I am forced to write the immutable twice even > though it is pretty obvious that the class cannot be mutated.
Honestly, from what I understand of how this works, what I find weird is the struct case. immutable on classes does _not_ make the class itself immutable. It just makes all of its members immutable - hence the error about trying to allocate new Foo instead of new immutable Foo. So, that is exactly what I would expect. And honestly, being able to write Foo and have it imply immutable Foo would get _really_ confusing when reading and debugging code. What's bizarre is that marking the struct with immutable would affect anything other than its members. Bar b; should not claim that typeof(b) is immutable(Bar). b was not marked as immutable. It was listed as Bar, not immutable Bar. So, b shouldn't be immutable. - Jonathan M Davis