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