Const template
Andrei Alexandrescu (See Website for Email)
SeeWebsiteForEmail at erdani.org
Sat Jan 20 15:40:07 PST 2007
Chris Nicholson-Sauls wrote:
> Andrei Alexandrescu (See Website for Email) wrote:
>> 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(); }
>> }
>>
>> 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.
>>
>> 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
>
> Its not a bad idea, although with a little more flavor added to Tuples,
> template Const might become more general and therefore more usable.
> Particularly if we could get an 'identifier' construct in templates such
> as has been asked for before, and specializations that mimic what 'is'
> expressions can do, and a true "static foreach". (I know, its a long
> list of wants.)
Let's see:
1. The 'identifier' construct is likely to make it in D 2.0. Walter and
I discussed it (the feature moniker that we use is "new alias") and
there is a clear understanding of its necessity. So - check that one.
2. static foreach is a definite go. It's necessary for compile-time
reflection. Walter acknowledged that himself on several occasions. Check
that one too.
3. Specializations that mimic what 'is' expressions can do... not sure I
understand that one. Check it too :o).
> struct Const (T : struct) {
> private T* ptr ;
>
> static Const!(T) opCall (inout T t) { ptr = &t; }
>
> static foreach (field; T.tupleof) {
> typeof(field) identifier(field.nameof) () { return *ptr.field; }
> }
> }
I had in mind something a tad more comprehensive:
struct Const (T : struct) {
private T* ptr ;
// This sucks. Hopefully this() will make it in.
static Const!(T) opCall (inout T t) { ptr = &t; }
static foreach (field; T.tupleof) {
typeof(field) field() { return *ptr.field; }
}
static foreach (fun; T.functionsof) {
static if (fun.mutator) continue;
fun.result fun(fun.argsOf args) { return ptr->fun(args); }
}
}
> It loses the mapping to functions, though. I almost have to admit a
> 'const' like parameter storage class might well be the way to go.
> Either the 'byref' that has been mentioned previously, or a reuse of
> either 'static' or (*sigh*) 'const'.
The problem is that D does not have a clear stance on what a storage
class is, and how it is to be manipulated statically. It is unclear
whether storage is part of the type or a separate attribute of an
expression. If this is not solved, it will inflict unbounded amounts of
pain onto template code. Wiring more storage classes (such as 'lazy'
which I realized Wednesday was a bad idea as it murks things even more
and is thoroughly ill-designed because it is a storage class that
actually changes the syntax of the object use -- someday Walter should
stand the pressure and stop adding features just because people say they
seem cool) into the language is not going to help any. Heck that was a
long sentence :o).
Andrei
More information about the Digitalmars-d
mailing list