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.


Reply via email to