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