Inherited const when you need to mutate

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Wed Jul 11 05:55:40 PDT 2012


On 7/11/12 3:58 AM, Don Clugston wrote:
> Something I wonder about, though, is how many different use cases are we
> dealing with?
>
> Suppose we had a caching solution (you could think of it as @cached, but
> it could be done in a library). The user would need to provide a const,
> pure function which returns the same value that is stored in the cache.
> This is enforceable. The only way to write to the cache, is by calling
> the function.
>
> How far would that take us? I don't think there are many use cases for
> logically pure, apart from caching, but I have very little idea about
> logical const.

I think a caching solution would cover most valid needs and indeed would 
be checkable.

We can even try its usability with a library-only solution. The idea is 
to plant a mixin inside the object that defines a static hashtable 
mapping addresses of objects to cached values of the desired types. The 
destructor of the object removes the address of the current object from 
the hash (if there).

Given that the hashtable is global, it doesn't obey the regular rules 
for immutability, so essentially each object has access to a private 
stash of unbounded size. The cost of getting to the stash is 
proportional to the number of objects within the thread that make use of 
that stash.

Sample usage:

class Circle {
     private double radius;
     private double circumferenceImpl() const {
         return radius * 2 * pi;
     }
     mixin Cached!(double, "circumference", circumferenceImpl);
     ...
}

auto c = new const(Circle);
double len1 = c.circumference;
double len2 = c.circumference;

Upon the first use of property c.circumference, Lazy computes the value 
by calling this.circumferenceImpl() and stashes it in the hash. The 
second call just does a hash lookup.

In this example searching the hash may actually take longer than 
computing the thing, but I'm just proving the concept.

If this is a useful artifact, Walter had an idea a while ago that we can 
have the compiler help by using the per-object monitor pointer instead 
of the static hashtable. Right now the pointer points to a monitor 
object, but it could point to a little struct containing e.g. a Monitor 
and a void*, which opens the way to O(1) access to unbounded cached 
data. The compiler would then "understand" to not consider that date 
regular field accesses, and not make assumptions about them being immutable.

Any takers for Cached? It would be good to assess its level of 
usefulness first.


Andrei


More information about the Digitalmars-d mailing list