Class templates with types determined at runtime

Doctor J nobody at nowhere.com
Tue Apr 7 22:14:29 PDT 2009


Daniel Keep Wrote:
> 
> The major problem with this is that you're trying to get into a
> situation where you don't know the type of T at compile-time, and you
> CANNOT do that.

Exactly -- I have been using Python lately. :)  But wouldn't it be nice to have something like implicit template instantiation (or type inference) based on the possible return types of a (variant) function?  I'm sure there are lots of good reasons why it isn't done, but it would be convenient...

Thinking about this a little more, it seems the question is not "can I avoid the switch?" because it has to happen somewhere, but "can I put the switch in the module that determines the type of the class, rather than at the 'top level' where the class variable is declared?"  Or put another way, can I declare a variable with unspecified type parameters, assign it the result of a variant-return-type function, and have the compiler generate code for all the possibilities behind the scenes?  This is 98% of the way to dynamic typing; the only difference being the set of possible types is circumscribed at compile time.

It seems to strike at the heart of the static/dynamic typing dichotomy.  Can a function return multiple types?  (And not just the polymorphism kind of multiple types.)  It would get you many of the benefits of dynamic typing, but also some of the drawbacks ("what is the type of the expression I'm staring at?  I don't know until I run it!  Will it break with type T?  I don't know until I run it!").  It would let generic types out of the confines of templates, which might frighten people.  And at any rate, it sounds like a lot to ask of a strongly statically typed language.  

> Something like this:
> 
> -----
> import std.stdio;
> import std.math;
> import std.boxer;
> 
> void dostuff(Box cont)
> {
>     if( unboxable!(float)(cont) )
>         writefln("%.12f", unbox!(float)(cont));
> 
>     else if( unboxable!(double)(cont) )
>         writefln("%.12f", unbox!(double)(cont));
> }
> 
> int main(string[] args)
> {
>     string precision = "double";
>     if (args.length > 1 && args[1] == "single")
>         precision = "single";
> 
>     auto cont = newContainer(precision);
>     dostuff(cont);
> 
>     return 0;
> }
> 
> Box newContainer(string precision)
> {
>     switch (precision)
>     {
>         case "single":
>             return box( cast(float) PI );
>         case "double":
>             return box( cast(double) PI );
>         default:
>             /+
>             // exit?  Eurgh!
>             writefln("Error: unknown type '%s'.", precision);
>             exit(1);
>             +/
>             throw new Exception("unknown type " ~ precision);
>     }
> }

I appreciate the suggestion.  But from an "ideal language" perspective, this is a workaround for a shortcoming of D, right?  The price for a pretty main() is repeating the code I'm trying to avoid, twice.  Mmm, tradeoffs.  I'll think about it.  

Thanks for your help.




More information about the Digitalmars-d-learn mailing list