December 15, 2006
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
December 15, 2006
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