April 27, 2013
On Friday, 26 April 2013 at 21:14:54 UTC, Walter Bright wrote:
> On 4/26/2013 12:37 PM, Jonathan M Davis wrote:
>> There's nothing whatsoever about bool that
>> makes sense as an integral type.
>
> This is where our perspectives sharply diverge. A bool is a 1 bit integer type.

Then why does it convert from int by comparing with 0 ? That isn't the behavior of an integral.
April 27, 2013
On Friday, 26 April 2013 at 21:32:32 UTC, Tove wrote:
> On Friday, 26 April 2013 at 21:01:17 UTC, Brian Schott 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?
>>
>> The idea of a "true number" and a "false number" doesn't make sense, so yes.
>
> I find the current implementation perfectly intuitive and I wouldn´t want it any other way... it models the underlying hardware, just the way it should be.
>
> Sometimes due to bad coding standards I´m forced to write...
> if((.....long expression with not immediately apparent operator precedence)!=0)
> ... absolutely appalling, kills readability with extra () etc. doesn´t matter how many years, I was forced to do it, I still cringe every time I see a line like that and itch to rewrite it more readable.
>

That is totally irrelevant as a cast is already inserted automatically.
April 27, 2013
On Friday, 26 April 2013 at 21:37:14 UTC, Walter Bright wrote:
> On 4/26/2013 1:59 PM, Andrej Mitrovic wrote:
>> On 4/26/13, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
>>> An even better example:
>>
>> import std.stdio;
>>
>> void foo(bool x) { writeln("1"); }
>> void foo(long x) { writeln("2"); }
>>
>> void main()
>> {
>>     foo(1);  // "1"
>>     foo(false ? 2 : 1);  // "2"
>> }
>>
>> Kill it with fire.
>
> How about this one:
>
> import std.stdio;
>
> void foo(short x) { writeln("1"); }
> void foo(long x) { writeln("2"); }
>
> void main()
> {
>      foo(30000);  // "1"
>      foo(false ? 40000 : 30000);  // "2"
> }


Walter, you're completely missing the point.

The point is that people can live with the consequences of your short/long example, but they can't do the same with Andrej's bool/long example.

No matter how right you are, if you keep insisting your way is correct, D will continue never becoming popular because people will continue finding it hard to use.

I think at some point it's worth noticing that "ease of use" is _not_ a linear function of "technical correctness". You may be right in technicality but that doesn't mean you're right on the UI side.
April 27, 2013
On Saturday, 27 April 2013 at 01:43:12 UTC, deadalnix wrote:
> On Friday, 26 April 2013 at 21:14:54 UTC, Walter Bright wrote:
>> On 4/26/2013 12:37 PM, Jonathan M Davis wrote:
>>> There's nothing whatsoever about bool that
>>> makes sense as an integral type.
>>
>> This is where our perspectives sharply diverge. A bool is a 1 bit integer type.
>
> Then why does it convert from int by comparing with 0 ? That isn't the behavior of an integral.

+1
April 27, 2013
On Friday, 26 April 2013 at 21:34:44 UTC, Walter Bright wrote:
> On 4/26/2013 1:59 PM, Diggory wrote:
>> The actual value shouldn't be taken into
>> account when determining which overload to call, only the type should matter,
>
> D has an interesting feature called VRP (value range propagation), where implicit conversion very much depends on the value. For example:
>

Then perhaps ban VRP on arguments if it affects overloading?
April 27, 2013
On Saturday, 27 April 2013 at 01:37:22 UTC, deadalnix wrote:
> On Friday, 26 April 2013 at 19:22:51 UTC, Walter Bright wrote:
>> I remember once a language that tried to define true and false as something other than 1 and 0. It was horrible.
>
> Don't need to look far away. Most shell do that.

D can still cast true to 1 and false to 0. It is solely the implicit casting that is inappropriate under rather common circumstances.

--rt
April 27, 2013
Is this what some of you are asking for?

bool a = true;             // ok
bool b = false;            // ok
bool c = 1;                 // error, no implicit conversion
bool c = getInt();        // error? ok?
int x = 42;
if(x) { ... }                   // ok (doesn't this imply c = getInt() ok too?
if(42) { ... }                 // ok
April 27, 2013
On Thu, 25 Apr 2013 23:01:30 -0700, Walter Bright <newshound2@digitalmars.com> wrote:

> 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.

I think the issue (and I am firmly in the foo(1) => long camp) is that bools are considered better integers than actual integer types (or even floating point types for that matter).  I agree that bools can be implicitly cast to and from integers, as a last resort.

> 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.

bool is true or false.  It can be interchangeable with 0 or 1.  But if it's overloaded with an integral or otherwise numeric type (float, double, etc), then the numeric type should be chosen first, or ambiguity flagged (your choice).  The current behavior is as bad as if();  That's not ambiguous, and follows the grammatical rules, why does that deserve a special case and this not?

> The real issue is do you want to have the implicit conversions:
>
> 0 => false
> 1 => true
>
> or would you require a cast?

This is irrelevant to the problem.  If one wants to pass a boolean literal, they would use true or false, not cast(bool)1 or cast(bool)0.  When an implicit cast must be done, and overload selection is at stake, bool should be last on the list of numeric types.

I think you are incorrectly making this into a "it has to be this way for consistency" issue, it's not.  It's an arbitrary rule, with very little sense involved.

-Steve
April 27, 2013
On Saturday, 27 April 2013 at 05:54:48 UTC, Luís Marques wrote:
> Is this what some of you are asking for?
>
> bool a = true;             // ok
Yes

> bool b = false;            // ok
Yes

> bool c = 1;                 // error, no implicit conversion
Yes

> bool c = getInt();        // error? ok?
Yes (error)

> int x = 42;
> if(x) { ... }                   // ok (doesn't this imply c =
Yes

> getInt() ok too?
Yes

> if(42) { ... }                 // ok
Yes
April 27, 2013
On Friday, 26 April 2013 at 21:37:14 UTC, Walter Bright wrote:
> On 4/26/2013 1:59 PM, Andrej Mitrovic wrote:
>> On 4/26/13, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
>>> An even better example:
>>
>> import std.stdio;
>>
>> void foo(bool x) { writeln("1"); }
>> void foo(long x) { writeln("2"); }
>>
>> void main()
>> {
>>     foo(1);  // "1"
>>     foo(false ? 2 : 1);  // "2"
>> }
>>
>> Kill it with fire.
>
> How about this one:
>
> import std.stdio;
>
> void foo(short x) { writeln("1"); }
> void foo(long x) { writeln("2"); }
>
> void main()
> {
>      foo(30000);  // "1"
>      foo(false ? 40000 : 30000);  // "2"
> }

VRP should be used as a fallback mechanism. Yes, kill it with fire.