An interesting subject is being debated by some of the heavy hitters of D
on the latest beta on the announce NG.
However, I have found that there is an inconsistency in TDPL that needs to
be addressed.
Forgetting the controversy currently brewing, we have the following
current situation:
struct S
{
immutable int x;
this(int n)
{
x = n;
int y = x;
x = 0;
}
}
This compiles, and shows that one can use an immutable, and then the
immutable can be changed. This is no good, for obvious reasons.
TDPL does not specifically address this issue (from what I can find via
manual search), but it does talk about immutable constructors. It's
prescription is for immutable constructors to be prohibited from reading
any members, and prohibited from calling any functions with 'this' as a
parameter. You are allowed to write the members as many times as you
want. The idea is if you can't read the data, it can't be inconsistent.
Note that this mechanism is not currently implemented in the compiler.
I thought "great, let's apply the same technique here". But we have a
problem. It would be too restrictive to say you can't call another member
function or any other function in a *normal* ctor, just because you
declared an immutable member. An immutable member is generally set once
and then read from then on.
I think both mechanisms (protecting immutable members in the ctor, and
protecting all members in an immutable ctor) should be consistent. I
think the 'no calling any functions' restriction is to restrictive to
apply to normal ctors.
My leaning is to re-define how immutable ctors and normal ctors that can
initialize immutable members should behave. The immutability should be
applied on the first read of the member, or calling a member
function/passing 'this' somewhere. Some flow analysis is required for
this, but we can be pretty conservative about it. There aren't too many
use cases for this stuff anyway.
What do you think?
-Steve