literals

Steven Schveighoffer schveiguy at yahoo.com
Mon Mar 29 03:57:42 PDT 2010


On Sun, 28 Mar 2010 15:09:35 -0400, so <so at so.do> wrote:

> On Sun, 28 Mar 2010 23:46:55 +0400, Steven Schveighoffer  
> <schveiguy at yahoo.com> wrote:
>> What you are asking for is a template instantiation that depends on  
>> instantiating itself.  How about a function like this?
>>
>> void foo(int x);
>>
>> T inv(T)(T m) {
>>     foo(m);
>>     return 1.0/m;
>> }
>>
>> How do you know what type to use for T?  It's simple when you make inv  
>> a one-liner, there is only one thing to look at.  But as you start  
>> making the function more complex, then it's impossible to tell what the  
>> user actually wants.   In this instance, T must be implicitly  
>> convertable to int, but also must be a floating point type.  Clearly  
>> there is an error here, but where is it?  This is called ambiguity, and  
>> to avoid it, the compiler makes a decision, right or wrong, based on  
>> the literal used to call the function.  It expects you, the user, to  
>> help out when it doesn't make the right one.  I don't think it's too  
>> much to ask.  It's simply a tradeoff between being an all-powerful  
>> oracle-like compiler and being a simple-to-write compiler.
>
> I don't think a language/compiler should make premature decisions when  
> an ambiguity happens,
> What is warning or error mechanism for then?

It has to make a decision on literals, or else you can't use them without  
casting.  I'd hate to write code for a compiler that requires you to cast  
every literal.

> In your case, we have a rule at hand, and you broke it. That should  
> require an explicit cast,
> Also, when you have a framework, you would have the T version of the  
> "foo" right? I guess i am missing something here.

What you are missing is it's easy to look at a simple example and conclude  
that a compiler should have enough intelligence to understand what you  
meant in that simple example.  However, you must also look at more complex  
cases and figure out if the rule holds for those as well.  I think in your  
simple one-liner, it is obvious to a person that inv only compiles for  
floating point types.  However, you want it to work for the literal "5",  
right?  So you want the compiler to use the code of the function to deduce  
what the type of 5 is, knowing that the function should compile for  
floating point types.  It just isn't a workable general solution.  Code  
can be very complex, and to require the compiler to understand the  
semantic meaning of the code in this way is not how the D compiler is  
built.  It is *told* how to compile something, and then checks that what  
you told it to do makes sense.  It doesn't figure stuff out for itself in  
anything bigger than a single statement.  D is supposed to be a  
context-free grammar.

>
>>
>> What the compiler sees when deciding to instantiate is this:
>>
>> T inv(T)(T m) {...}
>>
>> And it makes a decision.
>
> I am perfectly fine with that.

I am confused.  I thought this was your problem?  That it wasn't taking  
the body of the function into account when deciding the type of T?

>
>>
>> If you have a problem with writing inv(5.0) instead of inv(5), then  
>> maybe D just isn't for you.
>>
>> -Steve
>
> I am not sure what you mean really? You mean the other way around? i  
> want :
>
> inv(5.0f), inv(5.0d), inv(5.0L)
> or
> T x; inv(x); // where T is floating point type.

This works today, no (except for the d is redundant)?  I guess I don't  
really understand what you are looking for...

-Steve



More information about the Digitalmars-d mailing list