Logical const
Steven Schveighoffer
schveiguy at yahoo.com
Mon Nov 29 08:24:56 PST 2010
On Mon, 29 Nov 2010 10:56:14 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> wrote:
> On 11/29/10 8:56 AM, Steven Schveighoffer wrote:
>> 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.
>
> In fact it's possible to provide logical const with guarantees. You need
> a construct that keeps together a bool, a pure function/delegate/method,
> and a value, and works like this:
>
> class X
> {
> int x;
> lconst int y = { return x + 42; };
> void m1() { x = 2; invalidate(y); }
> void m2() const { writeln(y); }
> }
>
> You can use the intrinsic invalidate() against a non-const lconst field,
> but not against const lconst. Reading that field checks whether the
> field has been invalidated. If so, it writes the field with the result
> of the function/delegate/method and turns the validation flag on.
>
> With this system in place, I think the lconst value is guaranteed to be
> as strong as const.
This only solves the caching issue (which I agree is a large issue).
There are other cases where you want a mutable pointer to other data that
the object does not own. Such as a widget having a pointer to its
window. Assuming that window draw routines need to be non-const, a widget
cannot draw itself. You need to keep the widget to window relationship
outside the class, or cast. Both of these solutions are awkward at best.
> I recall I managed to convince Walter that the system works, but we
> agreed it would cost too much for what it does. I think it can be
> implemented as a library artifact under certain assumptions.
It would be nice to have user-defined annotations, so we could play with
possible implementations. As I recall, the acceptance of annotations in D
had not occurred when logical const was last discussed, and this seems
like a perfect candidate for annotations.
-Steve
More information about the Digitalmars-d
mailing list