Thread overview
Implicitly set template variables in D!
Aug 05, 2004
Nick
Aug 05, 2004
Sean Kelly
Aug 06, 2004
Nick
August 05, 2004
Yep! It's actually possible, but it isn't pretty :)

I've made a short example below. You have to use mixins to call the functions, and give the function parameters as template parameters. For the moment, though, you have to instantiate the templates explicitly somewhere else in the code, or you get a linking error. But this is a compiler bug and will likely be fixed in the future.

Also, you can't return values this way, but you can use as many inouts as you want :)

PS: This is ment as a fun hack, not as a 'serious' solution to the template problem. Enjoy!

# import std.stdio;
#
# // Actual function goes here
# template Bar(Y)
# {
#   Y Bar(Y param)
#     {
#       writefln("The parameter was: ", param);
#       Y dummy;
#       return dummy;
#     }
# }
#
# // Wrapper template (doesn't compile with DMD < 0.98)
# template Foo(alias X)
# {
#   typeof(X) _dummy_ = Bar!(typeof(X))(X);
# }
#
# // Now for some two-parameter action
# template Bar2(X, Y)
# {
#   X Bar2(inout X par1, Y par2)
#     {
#       writefln("Parameters were: ", par1, " and ", par2);
#       par1 = 5;
#       X dummy;
#       return dummy;
#     }
# }
#
# template Foo2(alias X, alias Y)
# {
#   typeof(X) _dummy_ = Bar2!(typeof(X),typeof(Y))(X, Y);
# }
#
# // This is only needed because of a compiler bug.
# void unused()
# {
#   Bar!(float);
#   Bar!(int);
#   Bar2!(int,float);
# }
#
# void main()
# {
#   float f = 1.2;
#   int j = 3;
#
#   // Look mah, no typename!!
#   mixin Foo!(f);
#   mixin Foo2!(j,f);
#   mixin Foo!(j);
# }


August 05, 2004
In article <cetqlb$1scn$1@digitaldaemon.com>, Nick says...
>
>Yep! It's actually possible, but it isn't pretty :)

Very clever :)  I did manage to shave down your example a bit here:

# import std.stdio;
#
# template Print( T )
# {
#     T Print( T val ) { writefln( "%s", val ); return val; }
# }
#
# template Call( alias Fn, RT, alias V1 )
# {
#     RT Call = Fn!( int )( V1 );
# }
#
# void main()
# {
#     Print!( int );
#     int x = 5;
#     mixin Call!( Print, int, x ) C1;
#     writefln( "%d", C1.ret );
# }

It has some weird limitations though.  The function has to return something, since it's not possible to assign void to something and a template can't contain just a statement.  Also, as you say it has to be a mixin otherwise there is the message: "cannot use local 'x' as template parameter."  And getting the return value is kind of a pain.  I can see how this could be extended to do some nifty things, but it seems a lot of hoops to jump through in order to get around typing "Print!(typeof(x))(x);"  Still, I'm going to play around with this some more later and see what else this little trick can accomplish :)


Sean


August 06, 2004
In article <cettal$1tu4$1@digitaldaemon.com>, Sean Kelly says...
>
># void main()
># {
>#     Print!( int );
>#     int x = 5;
>#     mixin Call!( Print, int, x ) C1;
>#     writefln( "%d", C1.ret );
># }

Nice! But specifying the 'int' sort of takes the point away, though. You probably meant it only to affect the return value type, but now it also sets the parameter type. If you want these to always be the same, you could get away with

# mixin Call!( Print, x ) C1;
# writefln(C1.ret); // Return value is here

Nick