immutable, const, enum

bearophile bearophileHUGS at lycos.com
Tue Apr 28 15:57:48 PDT 2009


Many thanks Steven Schveighoffer for the good explanations. Now I think I have understood what's one of the purposes of const. const arguments of a function just states that you aren't going to change the data inside a function/method, more or less like in C++, but in a transitive way.

But wasn't "in" before an argument type already doing that? I presume "in" isn't transitive. I have tried this:

import std.stdio: writeln;
void foo(in int* x) {
    (*x) = (*x) * 10;
    writeln(*x);
}
void main() {
    int y = 10;
    foo(&y);
}

But it doesn't work, so maybe in and const are the same thing now. Is "in" going to be removed then? Or maybe it's better to remove const and keep just a transitive "in". And I have seen "immutable ref" too is allowed, I guess it's mostly for performance reasons. Maybe "immutable in" is just for show, this works:

import std.stdio: writeln;

void foo(immutable in int x) {
    writeln(x * 2);
}
void main() {
    int y = 10;
    foo(y);
}

I want a simpler language -.-

While this doesn't work:

import std.stdio: writeln;

void foo(const in int x) {
    writeln(x * 2);
}
void main() {
    int y = 10;
    foo(y);
}

it prints: "redundant storage class in". So const and "in" seem really the same thing. But then what does it mean "immutable in"? I guess it just means transitive-immutable.

"immutable out" and "const out" are thankfully disallowed. So I guess "in" is now deprecated, it's just an alias of "const. But this idea seems wrong because "in ref" is disalloed but "const ref" is allowed, so they aren't just an alias of each other.

So the available ones are ("in" not listed to keep a bit of my sanity):
 immutable type
 const type
 out type
 immutable ref type
 const ref type
 type
 type*
 type**
 etc

-----------------------------

Christian Kamm:

> > immutable struct S {
> >     int x;
> >     this(int xx) { this.x = x; }
> > }
> 
> As far as I know, immutable has no effect on class declarations, so what 
> your code says is
> 
> struct S {
>     immutable int x;
>     this(int xx) immutable { this.x = x; }
> }
> 
> and that's causing problems. If you want an immutable instance, you can say:
> 
> auto c = new immutable(C)(10);

Sorry, the constructor was:
this(int xx) { this.x = xx; }


The following code works, and x can't be modified from outside the constructor:

import std.stdio: writeln;
immutable struct S {
    int x;
    this(int xx) { this.x = xx * 2; }
}
void main() {
    auto s = new S(10);
    writeln(s.x); // 20
}

I think it works because s is a mutable pointer to an immutable struct.

If you do this:
  auto s = S(10);  
The assignment doesn't work because s too is immutable.

Well, this idea may be false because a line of code just like this doesn't work:
  S(10);

I don't see ways yet to create an immutable struct on the stack.
Well... you can do:
S s = { 10 };
But then the constructor isn't called.


The following too works:

import std.stdio: writeln;
struct S {
    int x;
    this(int xx) { this.x = xx * 2; }
}
void main() {
    auto s = new immutable(S)(10);
    writeln(s.x);
}

I don't repeat similar experiments with immutable classes because they seem to never work to me.

I think I have already understood about 5% of this topic :-)

Bye,
bearophile



More information about the Digitalmars-d mailing list