preparing for const, final, and invariant

Regan Heath regan at netmail.co.nz
Mon May 21 03:48:46 PDT 2007


Walter Bright Wrote:
> Bill Baxter wrote:
> > Walter Bright wrote:
> >> Another option is to reuse 'inout' to mean 'mutable', since 'inout' is 
> >> replaced by 'ref'.
> > ...which is what my last message was suggesting.
> 
> You're right, I read your posting too quickly.
> 
> > Any reason why that wouldn't work?
> 
> Breaking existing code.
> 
> > There is the question of what would happen to "out" and 
> > how you'd get out behavior applied to the pointer rather than the value.
> 
> I'd leave out as it is.
> 
> > And while "mutable" is on the table, is D going to have a story for 
> > private mutable members that don't affect the interface?  Like the 
> > classic private mutable cache member in C++.
> 
> Ah, the "logical constness" design pattern. I personally loathe that 
> <g>. Const but mutable data just smacks of being far too clever.

My feeling is that if we have 'scope const final' as default and implicit then we do need some way to escape it, as we've all suggested.

I think the best way is as Daniel suggested, any keyword will override the implicit/default ones, so:

void foo(int i) {}  //scope, const, final
void foo(const int i) {} //just const
..etc..

So, that just leaves the problem you (Walter) proposed of:

>class C { int x; }
>void foo(C c)
>{
>     c.x = 3;
>}

and being able to pass a mutable reference.

Would this reference be 'scope' or 'final'?  My understanding is that 'final' means the reference itself could not be changed and 'scope' means an outside reference cannot be given it's value.

It seems to me you want both of these ('scope' because the reference will persist outside the function and 'final' because the very point of 'ref' is to be able to modify the reference) except in cases where you pass it by 'ref', in which case you want neither.  

Assuming we want 'scope' and 'final' applied to these mutable references then I dislike re-using 'inout' because (and perhaps this is ingrained thinking due to having used inout and out) the 'out' part of the keyword doesn't immediately appear to be happening.  We're not setting the reference to something which is then used 'out'side the function, instead (as Bill mentioned) we're changing them internally and only in this way is it reflected outside the function.

I'd think I'd prefer to use a new keyword like 'mutable', which in our case would be a shortcut for 'scope final'.

In a general sense it seems we have 2 classes of keyword here, the base ones:

const
final
scope
ref

and these handy, shortcut, combination ones:

in(default) = const, scope, final
mutable = scope, final

The question I think we need to ask before we decide what keyword to use is:  do we want/need to have opposites for all the base keywords? or do we want to use !<keyword>? or do we want something else?

I dislike !<keyword> purely for aesthetic reasons, to me it looks *ick*.

So, if we had opposites what would they be?

const - mutable?
scope - global?
final - mutable?

I seem to have hit a little wall here, we can't use mutable for both the opposite of const and final, and then also for the combination of 'scope final', can we?

It seems I have asked more questions than given answers, hopefully someone else can come up with a few solutions :)

Regan Heath



More information about the Digitalmars-d-announce mailing list