D const design rationale

Sean Kelly sean at f4.ca
Fri Jun 22 08:40:43 PDT 2007


Walter Bright wrote:
> Sean Kelly wrote:
>> Walter Bright wrote:
>>> http://www.digitalmars.com/d/const.html
>>
>> So in short, 'const' protects data and 'final' freezes references.  
>> How do these two apply to an int declaration?
>>
>>     const final int x = 5;
>>
>> Is either a compiler error? are they synonyms in this case?
> 
> It's not an error, it's just redundant.

Okay, thanks.

>> This aspect of the design seems very straightforward, aside from the 
>> question above.  What bothers me, however, is the use of 'invariant'. 
>> Adding a third keyword simply to represent data that's "really really 
>> const" just confuses things to me, and I haven't been able to get past 
>> this.
> 
> invariant = the data doesn't change
> const = the data cannot be changed through this reference to it

And a 'const' at the declaration point implicitly means 'invariant'.

>> Given that adding a third keyword doubles the number of permutations 
>> for describing const behavior, I think the addition of 'invariant' 
>> should be very carefully considered.  Is there any way we could get 
>> along without it?  I realize that 'invariant' would be rarely used in 
>> practice, but that doesn't change the impact an additional attribute 
>> has on the complexity of this design.
> 
> In C++, sometimes const means invariant, and sometimes it means readonly 
> view. I've found even C++ experts who don't know how it works.

Odd.  The C++ system always seemed extremely simple to me.

>> Frankly, I think we could almost get away with one keyword, but for 
>> the fact that D doesn't use a reference qualifier for class 
>> references. About the only workaround I could think of to describe a 
>> const reference to mutable data would be something like this:
>>
>>     const (ref MyClass) x;
>>
>> And inserting the 'ref' seems even more confusing than simply having 
>> 'final' as in the current design.
> 
> C++ tries too hard to use one keyword to do it all. The result is, as 
> the article showed, serious difficulties.

I personally find the use of three keywords to represent three 
overlapping facets of const behavior to be very confusing, and am 
concerned about trying to explain it to novice programmers.  With three 
keywords, there are six possible combinations:

final
const invariant
final const
final invariant
const invariant
final const invariant

That some of these may be redundant just serves to further confuse the 
issue in my opinion.  So I wondered whether one of the keywords could be 
done away with.  Previously, you said 'invariant' may only apply to data 
whose value can be determined at compile-time, thus I imagine it can 
only apply to concrete/data types (ie. not classes).  Assuming this is 
true, I wonder whether there is truly a point in having 'invariant' at 
all.  Assuming it were done away with, the system becomes much simpler 
to me:

final
const
final const

And that's it.  'final' means a reference cannot be rebound, 'const' 
means the data cannot be altered (through the reference), and 'final 
const' means that both the reference is frozen and the data cannot be 
changed.  And that's it.  That the existence of invariant required the 
addition of parenthesis on class invariants just serves to strengthen 
the argument in my mind.  So in short, I'm just not convinced that 
'invariant' provides enough utility to warrant the cost in complexity 
and broken consistency (unittest doesn't require parens, so why does 
invariant?).


Sean



More information about the Digitalmars-d mailing list