www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Implicitly set template variables in D!

reply Nick <Nick_member pathlink.com> writes:
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);
# }
Aug 05 2004
parent reply Sean Kelly <sean f4.ca> writes:
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
Aug 05 2004
parent Nick <Nick_member pathlink.com> writes:
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
Aug 06 2004