On 2010-11-20 09:21:04 -0500, Peter Alexander <peter.alexander...@gmail.com> said:

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?

Using a static associative array as a cache will work:

        class Matrix
        {
                double getDeterminant() const
                {
                        static double[const(Matrix)] cache;
                        if (auto resultptr = (this in cache))
                                return *resultptr;

                        auto result = /* expensive calculation */;
                        cache[this] = result;
                        return result;
                }
        }

and it'll continue to work even if you pass an immutable Matrix to different threads (each thread has its own cache). If you don't pass immutable Matrixes across threads, then you don't gain anything by making the function const.

The main reason D has const is to facilitate the usage of immutable. If you don't use immutable for a given type you generally shouldn't bother with const either.

But in any case, you always can cast away const if you really need to, just be sure of what you're doing. For instance, doing this breaks thread-safety for immutable Matrixes:

        auto mutableThis = cast(Matrix)this;
        mutableThis.cachedDeterminant = /* expensive calculation */;


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/

Reply via email to