www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - proposal: tthis for templates, or private aliases

reply Bill Baxter <dnewsgroup billbaxter.com> writes:
It gets tiring to type stuff like this:

template convertable_type_in_tuple(T, S...) {
     static if( is(S[0] : T) ) {
         const bool convertable_type_in_tuple =
                    convertable_type_in_tuple!(T, S[1..$]);
     } else static if(S.length == 0) {
         const bool convertable_type_in_tuple = true;
     } else {
         const bool convertable_type_in_tuple = false;
     }

}

This is the general pattern for recursive tuple templates.  You 
generally end up repeating the name of the template at least four times 
inside the body of the template.

Then you decide 'convertable_type_in_tuple' wasn't a good name and you 
have to be sure to correct it everywhere or you'll get compiler errors 
that only show up when that case is actually exercised.

So proposal option one is to give templates declared with the "template 
identifier(args)..." syntax to use a special kind of 'this', call it a 
template this or 'tthis', for lack of a better idea.

template convertable_type_in_tuple(T, S...) {
     static if( is(S[0] : T) ) {
         const bool tthis = tthis!(T, S[1..$]);
     } else static if(S.length == 0) {
         const bool tthis = true;
     } else {
         const bool tthis = false;
     }
}

Option 2 is to allow some sort of private alias in a template that 
doesn't interfere with the inner-name-matches-outer-name magic.

template convertable_type_in_tuple(T, S...) {
     private alias convertable_type_in_tuple tthis;
     static if( is(S[0] : T) ) {
         const bool tthis = tthis!(T, S[1..$]);
     } else static if(S.length == 0) {
         const bool tthis = true;
     } else {
         const bool tthis = false;
     }
}

Then at least you only have to type the name twice.
Option 2 would also be useful for function templates that use 
non-trivial derived types:

template function(T) {
    private alias typeof(T.init.member) RetT;
    RetT function(T val) {
       return val.member;
    }
}

--bb
Dec 14 2006
parent Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Bill Baxter wrote:
 It gets tiring to type stuff like this:
 
 template convertable_type_in_tuple(T, S...) {
     static if( is(S[0] : T) ) {
         const bool convertable_type_in_tuple =
                    convertable_type_in_tuple!(T, S[1..$]);
     } else static if(S.length == 0) {
         const bool convertable_type_in_tuple = true;
     } else {
         const bool convertable_type_in_tuple = false;
     }
 
 }
 
 This is the general pattern for recursive tuple templates.  You 
 generally end up repeating the name of the template at least four times 
 inside the body of the template.
 
 Then you decide 'convertable_type_in_tuple' wasn't a good name and you 
 have to be sure to correct it everywhere or you'll get compiler errors 
 that only show up when that case is actually exercised.
 
 So proposal option one is to give templates declared with the "template 
 identifier(args)..." syntax to use a special kind of 'this', call it a 
 template this or 'tthis', for lack of a better idea.
 
 template convertable_type_in_tuple(T, S...) {
     static if( is(S[0] : T) ) {
         const bool tthis = tthis!(T, S[1..$]);
     } else static if(S.length == 0) {
         const bool tthis = true;
     } else {
         const bool tthis = false;
     }
 }

I have suggested this several times in the past but by reusing "this" instead of adding a new keyword. I have even hacked GDC to try that out. :) The only potential problem I see with reusing "this" would be mixin templates for class constructors. Are they allowed today?
 Option 2 is to allow some sort of private alias in a template that 
 doesn't interfere with the inner-name-matches-outer-name magic.
 
 template convertable_type_in_tuple(T, S...) {
     private alias convertable_type_in_tuple tthis;
     static if( is(S[0] : T) ) {
         const bool tthis = tthis!(T, S[1..$]);
     } else static if(S.length == 0) {
         const bool tthis = true;
     } else {
         const bool tthis = false;
     }
 }

Yes. This has also been suggested several times in the past and would be extremely handy and save a lot of unnecessary typing. Once again, one potential problem is mixin templates. Does the "implicit template property" even apply to mixin templates?
 Then at least you only have to type the name twice.
 Option 2 would also be useful for function templates that use 
 non-trivial derived types:
 
 template function(T) {
    private alias typeof(T.init.member) RetT;
    RetT function(T val) {
       return val.member;
    }
 }

Something I have wished for several times is just having an "auto" return value for functions, as I often find a large portion of my template code just computing return values of trivial functions. /Oskar
Dec 15 2006