April 26, 2013
This is just silly.
Changing enum defaultVal = 1 to defaultVal = 2 should never result in calling a different overload.
April 26, 2013
On Friday, 26 April 2013 at 02:29:07 UTC, Jonathan M Davis wrote:
> On Thursday, April 25, 2013 17:35:34 Walter Bright wrote:
>> > Is bool more specialized than long
>> 
>> Yes, because a bool can be implicitly converted to a long, but a long cannot
>> be implicitly converted to a bool.
>
> However, given that bool isn't even an integral type, it seems very wrong that
> it would be a better match than something which _is_ an integral type. Given
> that the compiler already inserts explicit casts to bool in conditions to
> solve the primary case where you want a non-boolean value to implicitly
> convert to bool, it really seems to me that the other conversions to and from
> bool which are currently accepted are far too lax. Another example of this
> would be something like "foo" ~ true. I don't understand why conversions like
> that are allowed by the spec. They're just going to cause bugs.
>
> - Jonathan M Davis

And indeed they do. I did face some very weird bugs caused by that already.
April 26, 2013
On 4/25/2013 7:54 PM, Kapps wrote:
> This is just silly.
> Changing enum defaultVal = 1 to defaultVal = 2 should never result in calling a
> different overload.

This does:

------------------------
import core.stdc.stdio;

enum x = 10000;
enum y = 40000;

int foo(short s) { return 1; }
int foo(long s) { return 2; }

void main()
{
    printf("%d\n", foo(x));
    printf("%d\n", foo(y));
}
-------------------------

A bool is an integer with the range 0..1
April 26, 2013
On 04/25/2013 10:02 PM, Walter Bright wrote:> On 4/25/2013 7:54 PM, Kapps wrote:
>> This is just silly.
>> Changing enum defaultVal = 1 to defaultVal = 2 should never result in
>> calling a
>> different overload.
>
> This does:
>
> ------------------------
> import core.stdc.stdio;
>
> enum x = 10000;
> enum y = 40000;
>
> int foo(short s) { return 1; }
> int foo(long s) { return 2; }
>
> void main()
> {
>      printf("%d\n", foo(x));
>      printf("%d\n", foo(y));
> }
> -------------------------
>
> A bool is an integer with the range 0..1

It certainly behaves that way but it isn't an integer type and that's why it is unintuitive.

bool is a type with two values: false and true with the following conversion rules:

false -> 0
true -> 1
0 value -> false
non-zero value -> true
0 literal -> false

The following are the problematic ones:

1 literal -> true
non-zero and non-one *literal* -> Not a bool!

That last rule is the problem. Since we cannot get rid of the last rule, to be consistent, we should make literal 1 match an integer type better than bool.

Ali

April 26, 2013
On 4/25/2013 10:49 PM, Ali Çehreli wrote:
> It certainly behaves that way but it isn't an integer type and that's why it is
> unintuitive.

But it is an integer type.

> bool is a type with two values: false and true with the following conversion rules:
>
> false -> 0
> true -> 1
> 0 value -> false
> non-zero value -> true
> 0 literal -> false
>
> The following are the problematic ones:
>
> 1 literal -> true
> non-zero and non-one *literal* -> Not a bool!
>
> That last rule is the problem. Since we cannot get rid of the last rule, to be
> consistent, we should make literal 1 match an integer type better than bool.

Whether it's a problem or not depends on one's perspective.

The next issue is the notion of a "better" match. This notion is very complex in C++, and still produces odd results. Very few people can explain how it works - it's kind of shoot and hope you hit the target.

D tries very hard to avoid the notion of a "better" match. It goes with an exact match, followed by one with implicit conversions. All implicit conversions are considered equally good. Ambiguity is resolved by invoking "partial ordering", which was explained elsewhere in this thread. Partial ordering does not at all consider "better" matches.

Once you venture down the path of "better" matches, it's all roses at first, but look at where C++ wound up with it. It didn't intend to arrive there, it inevitably arrived there.

The real issue is do you want to have the implicit conversions:

0 => false
1 => true

or would you require a cast?

April 26, 2013
On Friday, 26 April 2013 at 05:02:50 UTC, Walter Bright wrote:
> On 4/25/2013 7:54 PM, Kapps wrote:
>> This is just silly.
>> Changing enum defaultVal = 1 to defaultVal = 2 should never result in calling a
>> different overload.
>
> This does:
>
> ------------------------
> import core.stdc.stdio;
>
> enum x = 10000;
> enum y = 40000;
>
> int foo(short s) { return 1; }
> int foo(long s) { return 2; }
>
> void main()
> {
>     printf("%d\n", foo(x));
>     printf("%d\n", foo(y));
> }
> -------------------------
>
> A bool is an integer with the range 0..1

This "feature" never has been useful to me. It has caused bug.
Additionally, the behavior is inconsistent :

int i = 1;
foo(i); // Don't call the bool version.
April 26, 2013
On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:
> The real issue is do you want to have the implicit conversions:
>
> 0 => false
> 1 => true
>
> or would you require a cast?

Yes.
April 26, 2013
On Friday, 26 April 2013 at 06:18:29 UTC, deadalnix wrote:
> On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:
>> The real issue is do you want to have the implicit conversions:
>>
>> 0 => false
>> 1 => true
>>
>> or would you require a cast?
>
> Yes.

+1

What about the implicit conversion for the other types? I could imagine that they could cause similar bugs. Why not get rid of the implicit conversion? How about yet another compiler flag?
April 26, 2013
On Friday, 26 April 2013 at 02:13:03 UTC, Ali Çehreli wrote:
> On 04/25/2013 06:44 PM, Maxim Fomin wrote:
>
> > On Thursday, 25 April 2013 at 21:05:43 UTC, Ali Çehreli wrote:
>
> > Looks like value range propagation bug because 1 is integer
> literal and
> > should be converted to long. There is no way for 1 to be
> converted to
> > bool here
>
> That special conversion rule of literal 0 and literal 1 being implicitly convertible to false and true gets in the way.
>
> > (from TDPL long is below int and it is the shortest way, value
> > range propagation can work upwards, but the path would be
> longer).
> Ali

Sorry but I am not aware of how 1 is converted to bool here.
True, that 1 is convertible to true, but here there is function
with long parameter.
April 26, 2013
On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:
> On 4/25/2013 10:49 PM, Ali Çehreli wrote:
>> It certainly behaves that way but it isn't an integer type and that's why it is
>> unintuitive.
>
> But it is an integer type.
>

Regarding bool type as integer type is C atavism and should be abandoned. This leads to comic sitatuation presented in the thread when changing literal to lvalue or using different enums changes overloading matching.