Const template

Dave Dave_member at pathlink.com
Sat Jan 20 12:18:54 PST 2007


Andrei Alexandrescu (See Website for Email) wrote:
> Chris Nicholson-Sauls wrote:
>> Just a thought: B) can be accomplished with an Interface that only 
>> exposes gettors.
> [snip]
>> <code>
>> interface IFoo {
>>   int alpha () ;
>>   int beta  () ;
>> }
>>
>> final class Foo : IFoo {
>>   private {
>>     int m_alpha ;
>>     int m_beta  ;
>>   }
>>
>>   final int alpha () { return m_alpha ; }
>>   final int beta  () { return m_beta  ; }
>>
>>   final int alpha (int x) { return m_alpha = x ; }
>>   final int beta  (int x) { return m_beta  = x ; }
>> }
>>
>> void somefunc (IFoo obj) {
>>   // do stuff with obj.alpha and obj.beta
>> }
>>
>> auto myfoo = new Foo;
>> somefunc(myfoo);
>> </code>
> 
> I think this is very interesting because it opens the door to a new
> implementation of const that I never thought of.
> 
> D is slated to have full-fledged compile-time reflection, meaning that
> you can find out all information about any given symbol, during
> compilation. So it turns out that a possible path to implement const is
> to make it a template. Given an arbitrary struct Foo, you could define a
> template called Const such that Const!(Foo) materializes into a struct
> that holds a Foo* inside, and exposes only the non-mutating parts of Foo.
> 
> So, given:
> 
> struct Foo
> {
>   int alpha, beta;
>   void nonmutator() { assert(alpha * beta != 0); }
>   void mutator() { alpha = beta; }
> }
> 
> the template Const!(Foo) generates the code:
> 
> struct Const!(Foo)
> {
>   private Foo* pFoo;
>   this(inout Foo foo) { pFoo = &foo; }
>   int alpha() { return pFoo->alpha; }
>   int beta() { return pFoo->beta; }
>   void nonmutator() { pFoo->nonmutator(); }
> }
> 

But you could still trivially and legally subvert this 'const'-ness:

     Const!(Foo) c(Foo(100,200));
     Foo* fp = *cast(Foo**)&c;
     fp.alpha = 10000;
     writefln(c.alpha);

So according to what Walter has said in the past about 'semantically meaningful const' then it 
wouldn't be enough to base optimizations on (even if the compiler could glean useful information 
from this).

> The reflection mechanism would have to provide the information whether
> or not a given member function changes the object.
> 
> The only drawback that I can think right now is that the compiler can't
> exploit this kind of constness with ease to generate better code; it's a
> "user-space" implementation with semantics that are hard to figure out
> at the compiler level.
> 

Both "user-space" and "compiler-space" const has been discussed at length in the past, and Walter's 
response has always been (paraphrasing) "D won't have const unless it is semantically meaningful 
(100% enforceable) by the compiler", which will never happen with a language like D.

> A minor drawback is that Const!(Foo) must be implicitly constructible
> from a Foo, but another in-design language feature (opImplicitCast) will
> take care of that.
> 
> 
> Andrei



More information about the Digitalmars-d mailing list