How do you properly use immutable on class members?

H. S. Teoh hsteoh at quickfur.ath.cx
Tue Mar 29 18:59:41 UTC 2022


On Tue, Mar 29, 2022 at 05:58:11PM +0000, Fruitful Approach via Digitalmars-d-learn wrote:
> I have immutable members:
> 
> `immutable immutable(Prop)[] axioms` which I can't initialize with
> Prop[], so I call this "immutable-poisoning" of the rest of my code.
> Can you provide a 10 line example of how to best work with immutable
> types, specifically immutable members, together with ctor, and
> accessor methods?

1) `immutable immutable(Prop)[]` is identical to `immutable(Prop[])`.
   Immutable is transitive. There is no need to spell it in such a
   verbose way.

2) Immutable fields can be initialized only in the ctor.

3) You *can* initialize immutable data with mutable data if it's a
   unique reference. Usually you get a unique reference by returning it
   from a pure function. For example:

	Prop[] makeProps() pure {
		return [ Prop.init ];
	}

	immutable(Prop[]) axioms = makeProps(); // OK

So in your case, what you could do is to initialize your immutable field
in your ctor, like this:

	class MyClass {
		immutable(Prop[]) axioms;

		private Prop[] makeAxioms() pure { ... }

		this() {
			axioms = makeAxioms();
		}
	}


[...]
> Every time I use const or immutable in C++ or D I end up failing with
> too many weird compilation errors, so I end up undoing all the places
> I inserted it.  Should I just _not use_ immutable or const except for
> on `const` method decoration where applicable?

D's const/immutable and C++'s const are very different beasts.  D's
const and immutable are transitive, meaning that if your outer reference
is const, then everything it refers to will also be const (we call it
"turtles all the way down").

Also, the way const interacts with mutable/immutable:

	         const
	         /   \
	(mutable)     immutable

Both mutable and immutable implicitly convert to const, but const does
not implicitly convert to mutable/immutable (in general; there are
exceptions like mutable -> immutable when it's a unique reference
returned from a pure function, e.g. above).

Basically, const means "I'm not allowed to change this, but somebody
else might". Immutable means "I'm not allowed to change this, neither is
anybody else."

As a general principle, const should be used when you're on the
receiving end of data that should not be changed (e.g., function
parameters); immutable should be used when you're the owner of data that
should not be change.


T

-- 
Holding a grudge is like drinking poison and hoping the other person dies. -- seen on the 'Net


More information about the Digitalmars-d-learn mailing list