Congratulations to the D Team!

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Wed Jul 11 08:27:55 PDT 2012


On 7/11/12 11:03 AM, Jakob Ovrum wrote:
> On Wednesday, 11 July 2012 at 12:36:43 UTC, Andrei Alexandrescu wrote:
>> I was a long-time proponent of this. It's less exciting than it may
>> seem actually.
>>
>> (a) Classes that work with const just fine incur one extra virtual
>> call. I think this can be avoided by having the compiler plant the
>> same pointer for the const and non-const version in the vtable.
>>
>> (b) Classes that can't do as little as one of these four operations
>> without mutating the object are completely excluded from the
>> immutability system, even if they'd otherwise benefit from it. Even
>> those that don't "care" they need to actively _work_ on not caring,
>> which doesn't sit well.
>>
>> So I don't see this as a viable solution to people who are fine with
>> const, but would like to use e.g. some lazy computation.
>>
>>
>> Andrei
>
> This solution is not for allowing people to use lazy computation in
> their const overrides, it's for allowing people to still use opEquals,
> toString etc. even if their implementations cannot and should not be const.
>
> e.g. the LuaD function I posted earlier - it has nothing to do with
> caching or lazy computation, it's just that it's only logically constant
> and cannot ever be bitwise constant due to the underlying API. Immutable
> instances of such structures are next to useless, as every member
> function except for a single getter function uses mutation.

I think I'll find it rather difficult to get behind modeling arbitrary 
escapes from immutability. If you want classes, you buy into a certain 
contract with inherent rights and constraints (starting with using 
references). It's a given, and again I find it unreasonable to ask that 
classes allow for arbitrary customization.

Your LuaD example goes like this:

     /**
      * Compare this object to another with Lua's equality semantics.
      * Also returns false if the two objects are in different Lua states.
      */
     bool opEquals(T : LuaObject)(ref T o) @trusted
     {
         if(o.state != this.state)
             return false;

         push();
         o.push();
         scope(success) lua_pop(state, 2);

         return lua_equal(state, -1, -2);
     }

You may be able to make this work by putting the state associated with 
push() and pop() in the Cache subsystem. If all else breaks, have 
opEquals assert(false, "Call bool lua_equals()").

We can't really model every possible design.


Andrei


More information about the Digitalmars-d mailing list