Class qualifier vs struct qualifier

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sat Jun 16 07:35:07 UTC 2018


On Saturday, June 16, 2018 07:13:28 Timoses via Digitalmars-d-learn wrote:
> On Thursday, 14 June 2018 at 17:07:09 UTC, Jonathan M Davis wrote:
> > Sure, it would save you a little bit of typing when you do
> > something like
> >
> > auto foo = new Foo;
> >
> > if makes it immutable for you, but it's at the cost of code
> > clarity.
>
> Why should it even?
>
> Isn't
>
>      immutable class C
>      {
>          int a;
>      }
>
> the same as
>
>      class C
>      {
>          immutable
>          {
>              int a;
>          }
>      }
>
> ?
>
> Does the following code clarify why an instance if immutable
> struct HAS to be immutable while an instance of class does not
> have to be immutable??
>
> immutable struct S {}
> immutable class C {}
>
> void main()
> {
>      S sa = S();
>      pragma(msg, typeof(sa)); // immutable(S)
>      S sb = S();
>      // sa = sb; // Error: cannot modify immutable expression sa
>
>      C ca = new C();
>      pragma(msg, typeof(ca)); // C
>      C cb = new C();
>      ca = cb; // works
> }
>
> Then the question would rather be why
>
> S s = S();  // immutable(S)
>
> does what it seems to be doing..?

It's perfectly legal to do

struct S
{
    int i;
    immutable int j;
}

and, declaring a variable of that type

S s;

does not result in the type of s being treated as immutable - just the
members. Similarly,

struct S
{
    immutable int i;
}

S s;

does not result in s being immutable(S). It's just when the struct itself is
marked as immutable that every variable of that type is suddenly treated as
immutable as well. And of course, with classes, marking the class as
immutable is identical to marking all of its members as immutable. Why
that's not the case for structs, I have no idea.

Regardless, I think that it's a terrible idea to implicitly make a type
immutable everywhere. If I see

S s;

I expect S to be mutable. Sure, it could have const or immutable members
(much as that's generally a terrible idea for structs, because it makes them
non-assignable and potentially non-copyable), but I would never expect the
type to be immutable(S) when the variable is clearly typed as S - just like
I wouldn't expect new S to result in an immutable(S). I was _very_ surprised
to see that the compile treats

immutable struct S
{
}

differently from

struct S
{
    immutable:
}

and I really think that it should be fixed so that it doesn't. The fact that

S s;

could ever result in the variable being anything other than S most
definitely breaks the principle of least surprise, and it doesn't match how
the rest of the language works. It's particularly bizarre when you consider
that it doesn't happen when all of the members are immutable if the struct
wasn't directly marked with immutable.

IMHO, even if a type were unusable as anything other than immutable,
variables of that type should still have to be marked with immutable,
otherwise the variable declaration doesn't match the actual type of the
variable, which seems like a terrible idea.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list