On Mon, 29 Nov 2010 10:56:14 -0500, Andrei Alexandrescu <seewebsiteforem...@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...@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

Reply via email to