Logical const

Steven Schveighoffer schveiguy at yahoo.com
Mon Nov 29 06:56:19 PST 2010


On Sat, 20 Nov 2010 09:21:04 -0500, Peter Alexander  
<peter.alexander.au at gmail.com> wrote:

> D does not support logical const due to the weak guarantees that it  
> provides.
>
> So, without logical const, how are D users supposed to provide lazy  
> evaluation and memoization in their interfaces, given that the interface  
> should *seem* const, e.g.
>
> class Matrix
> {
>    double getDeterminant() const { /* expensive calculation */ }
> }
>
> If it turns out that getDeterminant is called often with the raw matrix  
> data remaining unchanged, how can we add caching to this class without  
> rewriting the const-ness of all code that touches it?

This has been discussed at length on this newsgroup, and I argued for it  
for a long time.  You will not get any traction with Walter, because I've  
already proven that logical const == const, and it still doesn't change  
his mind.

The thing is we *already* have a hidden field that is logically const --  
an object's monitor.  Regardless of an object's constancy, you can always  
mutate the monitor.  The compiler does it by logically inserting a cast  
away from const, so that's what I'd suggest.

In reality, once you get into the realm of logical const, the compiler no  
longer helps you.  Any guarantees are now provided by you, not the  
compiler.

I've proposed a very complex system to allow you to indicate only certain  
fields as const which also worked with the existing const system.  While I  
think Walter and Andrei agreed it was possible, I agreed with them that it  
was too complex to ask users to deal with.

What I'd like to see is a solution like this:

struct S
{
    @mutable int i;
    int x;
}

S s;

lconst(S) *ls = &s; // new keyword!

ls.x = 5; // error
ls.i = 5; // OK

const(S) *cs = &s;
ls = cs; // error, less restrictive const version

I think a library solution would be more crude than what the compiler  
could do in this regard.  But another keyword, and complicating the const  
system further is probably too much tax for this feature.

In the end, I'd say just cast away const for the fields you want to  
change, and at least you can get your work done.

> And how do we write generic code when it's practically impossible to  
> determine const-ness from a glance? e.g. getDeterminant looks like it  
> should be const, but wouldn't be if it had caching, so writing generic  
> code that uses getDeterminant would be very difficult.

This is the point of Walter's objection.  Logical const is not const, so  
you would not be able to guarantee anything when you see const.

This kind of feature should only be used where the 'mutable' member is not  
considered part of the state of the object.  I.e. a cached calculation is  
a good example of this.  This rule is not enforceable, so it is up to you  
to determine applicability.

-Steve


More information about the Digitalmars-d mailing list