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.