Re: 1 matches bool, 2 matches long

2013-04-30 Thread Steven Schveighoffer
On Mon, 29 Apr 2013 11:39:27 -0700, Walter Bright  
newshou...@digitalmars.com wrote:



On 4/29/2013 10:10 AM, Steven Schveighoffer wrote:


I think you are inventing a strawman problem that this bug solves.   
There is no
need for a Better scheme, partial ordering works great, and so do  
true and false.


bool isn't an integer.  It can implicitly cast to an integer, but  
that's it.
Once we implement that rule, everything falls into place.  If you want  
to pass a
true boolean literal, use true.  If you want to pass a false  
boolean literal
use false.  Using 1 and 0 may be convenient, and may also be valid, but  
when it

matches an integral type as well as bool, then it's ambiguous.


Carefully reading your statement, you are still arguing that matching 1  
to long should be better than matching it to bool.


Yes, just like it's better matching to long than string.

-Steve


Re: 1 matches bool, 2 matches long

2013-04-30 Thread Rob T
On Tuesday, 30 April 2013 at 14:47:14 UTC, Steven Schveighoffer 
wrote:


Yes, just like it's better matching to long than string.

-Steve


More precise language is to state that there is no better match 
and long should simply not ever match with bool because long is 
not the same thing as bool, ie, bool should not be seen as an 
integral type because it clearly isn't because it does not behave 
like one and has a completely different purpose in the language 
otherwise there'd be no need for a bool to have special 
differences that the other integrals do not have.


How do we get the problem fixed? The sooner it is done the 
better, otherwise  we'll be forever stuck with subtle bugs and D 
programmers complaining about it for the rest of eternity.


--rt


Re: 1 matches bool, 2 matches long

2013-04-30 Thread Steven Schveighoffer

On Tue, 30 Apr 2013 10:43:01 -0700, Rob T al...@ucora.com wrote:


On Tuesday, 30 April 2013 at 14:47:14 UTC, Steven Schveighoffer wrote:


Yes, just like it's better matching to long than string.

-Steve


More precise language is to state that there is no better match and  
long should simply not ever match with bool because long is not the same  
thing as bool, ie, bool should not be seen as an integral type because  
it clearly isn't because it does not behave like one and has a  
completely different purpose in the language otherwise there'd be no  
need for a bool to have special differences that the other integrals do  
not have.


How do we get the problem fixed? The sooner it is done the better,  
otherwise  we'll be forever stuck with subtle bugs and D programmers  
complaining about it for the rest of eternity.


1. bool doesn't match to 1 or 0.
2. cast(bool)0 - false
3. cast(bool)(anything but 0) - true
4. true - (implicit cast) 1
5. false - (implicit cast) 0.

Then all that is left is to change any place where 1 or 0 implicitly casts  
to true or false to true and false.


The one casualty is any code that passes 1 or 0 to a function overloaded  
with long, short, or byte (or unsigned versions), and bool, will now  
silently switch to calling the integral version.  I would posit that this  
is extremely rare.


-Steve


Re: 1 matches bool, 2 matches long

2013-04-30 Thread Paulo Pinto

Am 30.04.2013 20:50, schrieb Steven Schveighoffer:

On Tue, 30 Apr 2013 10:43:01 -0700, Rob T al...@ucora.com wrote:


On Tuesday, 30 April 2013 at 14:47:14 UTC, Steven Schveighoffer wrote:


Yes, just like it's better matching to long than string.

-Steve


More precise language is to state that there is no better match and
long should simply not ever match with bool because long is not the
same thing as bool, ie, bool should not be seen as an integral type
because it clearly isn't because it does not behave like one and has a
completely different purpose in the language otherwise there'd be no
need for a bool to have special differences that the other integrals
do not have.

How do we get the problem fixed? The sooner it is done the better,
otherwise  we'll be forever stuck with subtle bugs and D programmers
complaining about it for the rest of eternity.


1. bool doesn't match to 1 or 0.
2. cast(bool)0 - false
3. cast(bool)(anything but 0) - true
4. true - (implicit cast) 1
5. false - (implicit cast) 0.

Then all that is left is to change any place where 1 or 0 implicitly
casts to true or false to true and false.

The one casualty is any code that passes 1 or 0 to a function overloaded
with long, short, or byte (or unsigned versions), and bool, will now
silently switch to calling the integral version.  I would posit that
this is extremely rare.

-Steve


+1


Re: 1 matches bool, 2 matches long

2013-04-30 Thread Timothee Cour
+1 (and give a helpful compiler error with suggested modification)


Re: 1 matches bool, 2 matches long

2013-04-30 Thread MattCoder

On Monday, 29 April 2013 at 18:39:27 UTC, Walter Bright wrote:

On 4/29/2013 10:10 AM, Steven Schveighoffer wrote:
On Sat, 27 Apr 2013 13:27:39 -0700, Walter Bright 
newshou...@digitalmars.com

wrote:
.
. .
bool isn't an integer.  It can implicitly cast to an integer, 
but that's it.
Once we implement that rule, everything falls into place.  If 
you want to pass a
true boolean literal, use true.  If you want to pass a 
false boolean literal
use false.  Using 1 and 0 may be convenient, and may also be 
valid, but when it

matches an integral type as well as bool, then it's ambiguous.


Carefully reading your statement, you are still arguing that 
matching 1 to long should be better than matching it to bool.



Walter, Don't you agree that the current way can be confusing?

For example, the following code generates 2 differents 
results/output:


import std.stdio;

void foo(bool b) { writeln(bool); }
void foo(long l) { writeln(long); }

void main()
{
long num = 0;

foo(num);
foo(0);
foo(2);
}

output:

long
bool
long

Regardless the fact that num is a variable (long), the first 2 
foo calls in my perspective means foo(0), and should generate the 
same output. Don't you agree with that?


Re: 1 matches bool, 2 matches long

2013-04-29 Thread Walter Bright

On 4/28/2013 2:05 AM, deadalnix wrote:

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:

On 4/27/2013 2:29 PM, Rob T wrote:

If bools are 1 bit ints, then why do we have 'true' and 'false' as keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.


VRP say you don't need to.


You're implying there is no need for 1L or 1U either, but there is.

The other reason, mentioned before, is that without making them a keyword or 
standard type, people will inevitably create their own in one of many different, 
incompatible, ways.


Re: 1 matches bool, 2 matches long

2013-04-29 Thread eles

On Friday, 26 April 2013 at 14:28:59 UTC, Rob T wrote:

On Friday, 26 April 2013 at 08:03:14 UTC, Walter Bright wrote:

On 4/25/2013 11:16 PM, deadalnix wrote:

This feature never has been useful to me.


It has been useful to me. So there!


Come on, characters are not an integral type, they are just an 
ordered and, for that reason, an indexed type. All the usual 
operations on characters apply to the index behnid (which is 
given by the ASCII/Unicode representation).


You are not adding characters, you are adding indices of those 
characters and so on. And you make a simple convention to always 
thing character for a givent (integer) index, since the index 
per se is of no much use without its equivalent representation 
from the ASCII table.


On the same grounds, one could index the values of bool form 4 to 
5 and assimilate false for 4 and true for 5, then go with the 
above convention.


There is a difference, however, between the bool and the char 
here: for the bool you want to go straight from the logical value 
to a conventional integral value, do not even think about some 
kind of tabular representation, while for the ASCII 
representation of char you seem to forget that such kind of a 
table exists in the first place.


Re: 1 matches bool, 2 matches long

2013-04-29 Thread Diggory

On Monday, 29 April 2013 at 06:26:44 UTC, Walter Bright wrote:

On 4/28/2013 2:05 AM, deadalnix wrote:
On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright 
wrote:

On 4/27/2013 2:29 PM, Rob T wrote:
If bools are 1 bit ints, then why do we have 'true' and 
'false' as keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.


VRP say you don't need to.


You're implying there is no need for 1L or 1U either, but there 
is.


The other reason, mentioned before, is that without making them 
a keyword or standard type, people will inevitably create their 
own in one of many different, incompatible, ways.


The same could be said of booleans. If D does not have a proper 
logical boolean type rather than a bit then people will simply 
write their own (conflicting and likely inefficient) boolean 
types which work the way they expect.


I've actually used a language where boolean is effectively a 
1-bit integer, and I can safely say that I have never found a 
single advantage over a language with more strongly type booleans 
which can implicitly be cast to int, but not the other way 
around. On the other hand the disadvantages are quite extensive: 
confusion for anyone who has ever used any other high level 
language, confusing overload resolution as shown in this thread, 
special cases (booleans convert by comparison rather than 
truncation, obviously truncation would be stupid but I think this 
is more of a reason to ditch integer booleans rather than to 
introduce a special case), different meaning (an integer is a 
number, a boolean is more like a yes/no enum and that is how it 
will be used in almost all code regardless of how it is defined 
in the language), etc.


Re: 1 matches bool, 2 matches long

2013-04-29 Thread eles

On Monday, 29 April 2013 at 09:49:59 UTC, Diggory wrote:

On Monday, 29 April 2013 at 06:26:44 UTC, Walter Bright wrote:

On 4/28/2013 2:05 AM, deadalnix wrote:
On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright 
wrote:

On 4/27/2013 2:29 PM, Rob T wrote:
this thread, special cases (booleans convert by comparison 
rather than truncation, obviously truncation would be stupid 
but I think this is more of a reason to ditch integer booleans 
rather than to introduce a special case), different meaning (an 
integer is a number, a boolean is more like a yes/no enum and 
that is how it will be used in almost all code regardless of 
how it is defined in the language), etc.


gdc:

bool x = false;
x++;

main.d:50: Error: operation not allowed on bool 'x'

why not? is just an integer after all. another special case?

this works:

int x = false;
x++;


Re: 1 matches bool, 2 matches long

2013-04-29 Thread deadalnix

On Sunday, 28 April 2013 at 19:38:26 UTC, eles wrote:

On Sunday, 28 April 2013 at 19:19:53 UTC, Walter Bright wrote:

On 4/27/2013 2:58 PM, jerro wrote:

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright
To reiterate, history amply shows that if 'true' and 'false' 
are not there, then people will define them themselves, 
inconsistently, and the end result is not helpful to anybody.



So basically, those are to be seen as simple #defines for 0 and 
1 and nothing more than that?


I am for a boolean type that is only true and false.

And, if so much needed conversion from int 0 and int non0 to 
boolean is needed in if() and while(), then simply add ifz(), 
ifnz(), whilez() and whilenz() to the language.


(that is: ifzero(), infnonzero(), whilezero(), whilenonzero()).



This is plain useless as a cast is already inserted here.


Re: 1 matches bool, 2 matches long

2013-04-29 Thread deadalnix
On Sunday, 28 April 2013 at 22:40:33 UTC, Andrei Alexandrescu 
wrote:

On 4/28/13 5:41 PM, kenji hara wrote:
Yes, as Andrei mentioned, it is sometimes useful. But, at 
least during

overload resolution, it must not occur.

Kenji Hara


Well the problem has other ramifications beyond bool. Consider:

import std.stdio;

int fun(short v1) { return 1; }
int fun(long v1) { return 2; }

void main(string[] args)
{
writeln(fun(10_000));
writeln(fun(100_000));
}

This prints 1 2. So the behavior of bool in this case is 
consistent with the behavior of other integral types.




For the same reason, both should call the long overload.


Re: 1 matches bool, 2 matches long

2013-04-29 Thread eles

On Monday, 29 April 2013 at 12:30:06 UTC, deadalnix wrote:

On Sunday, 28 April 2013 at 19:38:26 UTC, eles wrote:

On Sunday, 28 April 2013 at 19:19:53 UTC, Walter Bright wrote:

On 4/27/2013 2:58 PM, jerro wrote:

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright

This is plain useless as a cast is already inserted here.


so, only allow explict casting then.



Re: 1 matches bool, 2 matches long

2013-04-29 Thread deadalnix

On Monday, 29 April 2013 at 00:45:47 UTC, Mehrdad wrote:
On Monday, 29 April 2013 at 00:40:08 UTC, Andrei Alexandrescu 
wrote:
2. Stop allowing implicit bool-int conversions (explicit 
conversions like in if/while/etc. are of course not included 
here)


Unlikely to ever happen.


What's the use case against it?


This is useful, and do not cause problem by itself. The reverse 
conversion is problematic.


Re: 1 matches bool, 2 matches long

2013-04-29 Thread Mike James

gdc:

bool x = false;
x++;

main.d:50: Error: operation not allowed on bool 'x'

why not? is just an integer after all. another special case?


If you are going to create a boolean then use it as a boolean - it's not an 
integer any more. Don't mix and match - there's nothing worse than trying to 
follow some code that uses a variable in one way then, out of lazyness, uses 
it in a different way.




this works:

int x = false;
x++; 




Re: 1 matches bool, 2 matches long

2013-04-29 Thread eles

On Monday, 29 April 2013 at 14:08:20 UTC, Mike James wrote:

gdc:

bool x = false;
x++;

main.d:50: Error: operation not allowed on bool 'x'

why not? is just an integer after all. another special case?


If you are going to create a boolean then use it as a boolean - 
it's not an integer any more. Don't mix and match - there's 
nothing worse than trying to follow some code that uses a 
variable in one way then, out of lazyness, uses it in a 
different way.


that was exactly my point. that a boolean *should not* be an 
integer. and the case that I presented shows just another 
inconsistency of the relationship between booleans and integers 
in D. it works one way when it comes to function overloading, and 
another way when it comes to, let's say, ++ operator.




Re: 1 matches bool, 2 matches long

2013-04-29 Thread Steven Schveighoffer
On Sat, 27 Apr 2013 12:51:48 -0700, Walter Bright  
newshou...@digitalmars.com wrote:



On 4/26/2013 7:36 PM, Mehrdad wrote:

Walter, you're completely missing the point.


I completely understand it is a perception problem. Some people see bool  
as a 1 bit integer (including me). Some see bool as something very  
distinct from integers (including you).


short x = cast(short)0x1;
assert(x == 0);

bool b = cast(bool)2;
assert(b == 1);  // NOT 2s complement

bool is not an integer.  It doesn't behave like any other integer type.   
Because it has some power to implicitly cast to int, this does not make it  
an integer.


-Steve


Re: 1 matches bool, 2 matches long

2013-04-29 Thread Rob T

On Monday, 29 April 2013 at 14:08:20 UTC, Mike James wrote:

gdc:

bool x = false;
x++;

main.d:50: Error: operation not allowed on bool 'x'

why not? is just an integer after all. another special case?


If you are going to create a boolean then use it as a boolean - 
it's not an integer any more. Don't mix and match - there's 
nothing worse than trying to follow some code that uses a 
variable in one way then, out of lazyness, uses it in a 
different way.




this works:

int x = false;
x++;


The main point made in this thread is that because bool is not 
really an integral type, you cannot use it as one, but D 
overloads integral types with bool which is clearly wrong. You 
also cannot in general interchange ints and bools inside a 
template without special conditions to differentiate between them 
the two (eg ++bool fails), therefore bool should not overload on 
ints or implicitly cast to/from ints and bools under most 
situations.


--rt


Re: 1 matches bool, 2 matches long

2013-04-29 Thread Steven Schveighoffer
On Sat, 27 Apr 2013 13:27:39 -0700, Walter Bright  
newshou...@digitalmars.com wrote:



On 4/26/2013 11:04 PM, Steven Schveighoffer wrote:
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.


The overload system in D is explicitly not based on better. (The C++  
better overloading system is for functions, but not for templates.)  
The D overload system is based on partial ordering, which is the same as  
what C++ uses for templates.


I don't know for a fact, but I'm pretty sure the partial ordering scheme  
that C++ selected for templates, which came along many years later, was  
picked because people realized it was better (and more mathematically  
robust and defensible).


One of the problems with a better matching system is handling  
functions with multiple parameters, each with their own better match.  
(The C++ Standard devotes a great deal of complex text to this, it boils  
down to a bunch of rather arbitrary decisions.) Partial ordering solves  
this neatly and consistently.


As one who implemented C++'s better matching system, I can confidently  
state that the partial ordering scheme is FAR better overall.


I think you are inventing a strawman problem that this bug solves.  There  
is no need for a Better scheme, partial ordering works great, and so do  
true and false.


bool isn't an integer.  It can implicitly cast to an integer, but that's  
it.  Once we implement that rule, everything falls into place.  If you  
want to pass a true boolean literal, use true.  If you want to pass a  
false boolean literal use false.  Using 1 and 0 may be convenient, and  
may also be valid, but when it matches an integral type as well as bool,  
then it's ambiguous.


-Steve


Re: 1 matches bool, 2 matches long

2013-04-29 Thread Jonathan M Davis
On Monday, April 29, 2013 09:54:40 Steven Schveighoffer wrote:
 On Sat, 27 Apr 2013 12:51:48 -0700, Walter Bright
 
 newshou...@digitalmars.com wrote:
  On 4/26/2013 7:36 PM, Mehrdad wrote:
  Walter, you're completely missing the point.
  
  I completely understand it is a perception problem. Some people see bool
  as a 1 bit integer (including me). Some see bool as something very
  distinct from integers (including you).
 
 short x = cast(short)0x1;
 assert(x == 0);
 
 bool b = cast(bool)2;
 assert(b == 1); // NOT 2s complement
 
 bool is not an integer. It doesn't behave like any other integer type.
 Because it has some power to implicitly cast to int, this does not make it
 an integer.

It also isn't considered to be an integral type per std.traits.isIntegral. 
isIntegral only considers byte, ubyte, short, ushort, int, uint, long, and 
ulong to be integral types.

- Jonathan M Davis


Re: 1 matches bool, 2 matches long

2013-04-29 Thread Paulo Pinto

Am 29.04.2013 19:10, schrieb Steven Schveighoffer:

On Sat, 27 Apr 2013 13:27:39 -0700, Walter Bright
newshou...@digitalmars.com wrote:


On 4/26/2013 11:04 PM, Steven Schveighoffer wrote:

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.


The overload system in D is explicitly not based on better. (The C++
better overloading system is for functions, but not for templates.)
The D overload system is based on partial ordering, which is the same
as what C++ uses for templates.

I don't know for a fact, but I'm pretty sure the partial ordering
scheme that C++ selected for templates, which came along many years
later, was picked because people realized it was better (and more
mathematically robust and defensible).

One of the problems with a better matching system is handling
functions with multiple parameters, each with their own better
match. (The C++ Standard devotes a great deal of complex text to this,
it boils down to a bunch of rather arbitrary decisions.) Partial
ordering solves this neatly and consistently.

As one who implemented C++'s better matching system, I can confidently
state that the partial ordering scheme is FAR better overall.


I think you are inventing a strawman problem that this bug solves.
There is no need for a Better scheme, partial ordering works great,
and so do true and false.

bool isn't an integer.  It can implicitly cast to an integer, but that's
it.  Once we implement that rule, everything falls into place.  If you
want to pass a true boolean literal, use true.  If you want to pass a
false boolean literal use false.  Using 1 and 0 may be convenient, and
may also be valid, but when it matches an integral type as well as bool,
then it's ambiguous.

-Steve


Fully agree, I still not understand what is the issue to support the 
boolean strong typing other languages do offer.


--
Paulo


Re: 1 matches bool, 2 matches long

2013-04-29 Thread Walter Bright

On 4/29/2013 10:10 AM, Steven Schveighoffer wrote:

On Sat, 27 Apr 2013 13:27:39 -0700, Walter Bright newshou...@digitalmars.com
wrote:


On 4/26/2013 11:04 PM, Steven Schveighoffer wrote:

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.


The overload system in D is explicitly not based on better. (The C++
better overloading system is for functions, but not for templates.) The D
overload system is based on partial ordering, which is the same as what C++
uses for templates.

I don't know for a fact, but I'm pretty sure the partial ordering scheme that
C++ selected for templates, which came along many years later, was picked
because people realized it was better (and more mathematically robust and
defensible).

One of the problems with a better matching system is handling functions with
multiple parameters, each with their own better match. (The C++ Standard
devotes a great deal of complex text to this, it boils down to a bunch of
rather arbitrary decisions.) Partial ordering solves this neatly and
consistently.

As one who implemented C++'s better matching system, I can confidently state
that the partial ordering scheme is FAR better overall.


I think you are inventing a strawman problem that this bug solves.  There is no
need for a Better scheme, partial ordering works great, and so do true and 
false.

bool isn't an integer.  It can implicitly cast to an integer, but that's it.
Once we implement that rule, everything falls into place.  If you want to pass a
true boolean literal, use true.  If you want to pass a false boolean literal
use false.  Using 1 and 0 may be convenient, and may also be valid, but when it
matches an integral type as well as bool, then it's ambiguous.


Carefully reading your statement, you are still arguing that matching 1 to long 
should be better than matching it to bool.




Re: 1 matches bool, 2 matches long

2013-04-29 Thread Rob T
On Sunday, 28 April 2013 at 13:38:53 UTC, Andrei Alexandrescu 
wrote:

[...]
If enough differences accumulate to make bool quite a different 
type from a regular integral, then the matter of overloading 
with long, conversion from literals 1 and 0 etc. may be 
reopened. Even then, it would be a difficult decision.


I agree with most of what you said in your full post, except that 
in the quote above you are suggesting that there's a difficult 
decision to be made in the case of bool being it's own type 
rather than an integral type.


The opposite should be the case, where the decision to keep it as 
an integral is a difficult to defend.


I don't see where the difficulty is, because unless bool can 
exactly be treated as an integral, then it simply is not an 
integral, and unless it is an integral, it cannot be freely 
interchanged with the integrals.


The arguments in defense if bool as an integral are IMO weak.

For example, Walter mentioned the case of char successfully being 
treated as an integral type rather than a special case char' 
type. However, are there any differences between what char does 
and what byte does that interfere with each other? If char 
performs exactly like a integral type, then you can convincingly 
argue that it is an integral type.


Can the same thing with char be said about bool? No. You can only 
say that bool does share some, but not all the characteristics if 
an integral.


The other argument in favor boils down to a matter of convenience 
under some circumstances. Yes, there are a few cases where it is 
advantageous to interchange boolean 'true' and 'false' with 
integral 1 and 0, however the vast majority of uses do not rely 
on such an interchange, and even if such interchanges are used 
often, bool still has significant differences of behavior that 
exclude it from being considered as a fully interchangeable 
integral type (eg truncation behavior and differences with 
operators).


The best you can argue for, is that under some situations, bool 
should be freely interchanged with regular integrals, however 
that's not going to be true for all cases.


The conclusion ought to be that unless bool can be adjusted into 
behaving exactly like all the other integrals, then it simply 
cannot be freely interchanged as an integral in all cases, i.e., 
maybe OK in some cases, but certainly not all.


--rt


Re: 1 matches bool, 2 matches long

2013-04-29 Thread Sean Cavanaugh

On 4/29/2013 7:30 AM, deadalnix wrote:


(that is: ifzero(), infnonzero(), whilezero(), whilenonzero()).






int x = 3;
if (!!x)
{
// do something
}


Its not official but this already works in the C like langauges, as a 
way to 'promote to bool'





Re: 1 matches bool, 2 matches long

2013-04-29 Thread eles

On Monday, 29 April 2013 at 18:53:22 UTC, Sean Cavanaugh wrote:

On 4/29/2013 7:30 AM, deadalnix wrote:
Its not official but this already works in the C like 
langauges, as a way to 'promote to bool'


I know, but I still think that ifz() and ifnz() convey better 
(more, they are easier to debug, but that's subjective). However, 
is not a big deal.


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Walter Bright

On 4/27/2013 9:38 PM, kenji hara wrote:

On the other hand, D looks like having *special rule* of 0 and 1 literal for
boolean type. Even if the underlying rule is sane (partial ordering rule and
VRP), the combination makes weird behavior.


Again, whether it is weird or not comes from your perspective. From mine, a 
bool is a 1 bit integer. There is nothing weird about its behavior - it behaves 
just like all the other integer types.




Re: 1 matches bool, 2 matches long

2013-04-28 Thread deadalnix

On Sunday, 28 April 2013 at 08:40:01 UTC, Walter Bright wrote:

On 4/27/2013 9:38 PM, kenji hara wrote:
On the other hand, D looks like having *special rule* of 0 and 
1 literal for
boolean type. Even if the underlying rule is sane (partial 
ordering rule and

VRP), the combination makes weird behavior.


Again, whether it is weird or not comes from your 
perspective. From mine, a bool is a 1 bit integer. There is 
nothing weird about its behavior - it behaves just like all the 
other integer types.


Then be consistent. Convert int to bool by truncating.


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Walter Bright

On 4/27/2013 5:49 PM, Jonathan M Davis wrote:

Yes, but I honestly think that that's problem too. I think that there's more
of an argument for treating characters as integral types than bool, as they
really do hold an encoded number internally, but they really aren't treated as
integers in general, and I think that treating them as integers implicitly
tends to cause problems when conversions come into play.


Are you really solving a problem, or just creating new ones? I'd rather have a 
small set of simple, easily explained rules and accept a few issues with them 
than have a bewildering set of complicated rules trying to solve every problem.



True, it's nice to not have to cast '0' - 42 when assigning it back to a char,
but I also don't think that it's all that big a deal for the cast to be
required,


I've used languages enough that did require such casts. It left an enduring bad 
taste.



and I think that allowing things like foo ~ 42 is just asking for
bugs, particularly when you can easily do something like \u0042 if you
actually want a numberic character literal. foo ~ true just so happens to be
an extreme case of this, as it clearly makes no sense, and if it happens with
variables rather than literals, it's not necessarily as obvious that it's
happening.

We need to be careful with how strongly stuff is typed, because we don't want
to require casts everywhere, as that can introduce other types of bugs because
casts are so blunt - which is why not requiring casting when converting
between int and uint is probably ultimately a good idea - but characters and
bool really aren't integral types, even if they do have a relation to them,
and I firmly believe that treating them as integral types implicitly causes
more bugs than it fixes.


And I just as firmly believe they really are integral types. After all, we 
constantly manipulate them as integral types:


1. changing case
2. using them as array indices
3. doing utf encoding and decoding
4. generating hashes
5. sorting
6. encoding and decoding integer strings (printf/scanf)
7. compression/decompression
8. encryption/decryption

In fact, treating a char as a character actually seems to be in the minority 
of uses!



Clearly, with how the language currently works, that should raise a red flag,
but I think that it's clear that the majority of us would have expected
foo(bool) to work with bools, and foo(long) to deal with integral values,
allowing you to just have two overloads rather than several.


I don't think it is fundamentally different from the char issue.


It is definitely a matter of perspective, but I also think that it's fairly
clear that most people here don't expect bool to be treated as an integral
type and don't like the fact that it is. If it's truly an integral type, why
have true and false in the first place? Why not just use 1 and 0?


As history has amply shown, people simply like the true  false literals, and if 
we didn't supply them, they'd add them to their code in a multitude of 
incompatible ways (this was a considerable nuisance in C).



It seems like
implicit casting is making it so that there's no real difference between them,
and C++ introduced a bool type rather than sticking with C's approach in order
to be able to distinguish between bools and integers when overloading. We
appear to be doing a poor job of that.


There is a place for a 1 bit integer type, and bool fills that role nicely. That 
doesn't mean it isn't an integer, it's just a boundary case of integers.




Re: 1 matches bool, 2 matches long

2013-04-28 Thread deadalnix

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:

On 4/27/2013 2:29 PM, Rob T wrote:
If bools are 1 bit ints, then why do we have 'true' and 
'false' as keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.


VRP say you don't need to.


Re: 1 matches bool, 2 matches long

2013-04-28 Thread deadalnix

On Sunday, 28 April 2013 at 09:05:06 UTC, deadalnix wrote:

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:

On 4/27/2013 2:29 PM, Rob T wrote:
If bools are 1 bit ints, then why do we have 'true' and 
'false' as keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.


VRP say you don't need to.


Which is kind o funny, because we didn't had to wait for long 
before you felt in the trap as well. Hard to maintain it isn't 
confusing now . . .


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Rob T

On Sunday, 28 April 2013 at 09:05:06 UTC, deadalnix wrote:

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:

On 4/27/2013 2:29 PM, Rob T wrote:
If bools are 1 bit ints, then why do we have 'true' and 
'false' as keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.


VRP say you don't need to.


I was wondering who was going to notice that elephant. I didn't 
get a satisfactory answer to the question of why we have an int 
type named bool with special keywords true and false, when if it 
really is an int type, all we require is a type named bit with 
nothing else needed other than what is already available with int 
types.


bool is a very unusual beast, but why?

--rt


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Timon Gehr

On 04/28/2013 11:05 AM, deadalnix wrote:

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:

On 4/27/2013 2:29 PM, Rob T wrote:

If bools are 1 bit ints, then why do we have 'true' and 'false' as
keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.


VRP say you don't need to.


void foo(bool b){ } // 1
void foo(int i){ }  // 2

void main(){
foo(cast(bool)0); // calls 1
foo(0);   // calls 2
}


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Andrei Alexandrescu

On 4/28/13 4:40 AM, Walter Bright wrote:

On 4/27/2013 9:38 PM, kenji hara wrote:

On the other hand, D looks like having *special rule* of 0 and 1
literal for
boolean type. Even if the underlying rule is sane (partial ordering
rule and
VRP), the combination makes weird behavior.


Again, whether it is weird or not comes from your perspective. From
mine, a bool is a 1 bit integer. There is nothing weird about its
behavior - it behaves just like all the other integer types.


Let me start by saying that I agree with the view that this isn't a 
large or important issue; also, as language proponents with a lot of 
things to look at and work on, it seems inefficient to develop the 
language from one strident argument to another regardless of their true 
weight.


That being said, I don't think Walter is framing the problem correctly. 
The advantage of his approach is simplicity: bool is to the extent 
possible a 1-bit integer (with particularities stemming from its small 
size). (I presume it's an unsigned type btw.) That makes a lot of rules 
that apply to integers also apply automatically to bool. There remain a 
few peculiarities that have been mentioned:


1. The relationship between sizeof(bool), the cardinality of Boolean 
values, .min and .max etc are unlike that for integers.


2. Conversion rules from other integrals to bool (0 is preserved, 
nonzero is converted to 1) are different than among non-bool integrals 
(truncation etc).


3. A variety of operators (such as += or *=) are not allowed for bool.

These distinctions (probably there are a few subtler ones) and their 
consequences erode the simplicity advantage. Any serious argument based 
on simplicity should acknowledge that.


The larger issue here goes back to good type system design. At the 
highest level, a type system aspires to: (a) allow sensible and 
interesting programs to be written easily; and (b) disallow non-sensible 
or uninteresting programs from being written. Real type systems 
inevitably allow at least a few uninteresting programs to be written, 
and fail to allow some interesting programs. The art is in minimizing 
the size of these sets.


From that perspective, bool, as a first-class built-in type, fares 
rather poorly. It allows a variety of nonsensical programs to pass 
typechecking. For example, bool is allowed as the denominator in a 
division or reminder operation. There is no meaningful program that 
could use such an allowance: the computation is either trivial if the 
bool is true, or stuck if it's false.


Then there is a gray area, such as multiplying an integer by a bool; 
arguably a * b is a shortcut for if (!b) a = 0; or b ? a : 0 or a 
* (b ? 1 : 0) if b is a boolean. One might argue this is occasionally 
useful.


Then there is a firmer area of cooperation between bool and other 
numerics, e.g. a[0 .. a.length - b], where b is a bool. I'm seeing these 
in code now and then and I occasionally write them. I personally find 
code that needs to use a[0 .. a.length - (b ? 1 : 0)] rather pedestrian, 
but not unbearably so.


Tightening the behavior of bool to disallow nonsensical programs is 
arguably a good thing to do. Arguing against it would need to explain 
e.g. why operations such as b1 *= b2 (with b1 and b2 of type bool) 
were deemed undesirable but b1 / b2 was not.


If enough differences accumulate to make bool quite a different type 
from a regular integral, then the matter of overloading with long, 
conversion from literals 1 and 0 etc. may be reopened. Even then, it 
would be a difficult decision.


Finally, I felt compelled to add a larger point. This:


It's like designing a house with a fixed footprint. You can make the
kitchen larger and the bathroom smaller, or vice versa, but you can't
make them both bigger.


This is a terrible mental pattern to put oneself in. Design problems 
often seem - or can be framed - as such, and the zero-sum-game pattern 
offers a cheap argument for denying further consideration.


We've been stuck in many problems that looked that way, and the first 
step is to systematically destroy that pattern from the minds of 
everyone involved. We've been quite successful at that a few times: 
template constraints, integral conversions and VRP, cascaded comparisons 
a  b  c, ordering comparisons between signed and unsigned integrals, 
and more. They all seemed to be zero-sum design problems to which no 
approach was better than others; once that was removed and ingenuity was 
allowed to say its word, solutions that had escaped scrutiny came on the 
table. From the perspective of the zero-sum game, those are nothing 
short of miraculous.



Andrei


Re: 1 matches bool, 2 matches long

2013-04-28 Thread deadalnix
On Sunday, 28 April 2013 at 13:38:53 UTC, Andrei Alexandrescu 
wrote:

[Many things that make sense]


I think you missed a point I tried to raise several time 
unsuccessfully, and which is IMO very important.


VRP should behave as a fallback mechanism. IE, VRP should kick in 
when the situation would result as an error without. Integrals 
literals must be typed as integral types, so never match bool 
when an overload with an integral is available (same goes for 
byte or short).


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Walter Bright

On 4/28/2013 8:21 AM, deadalnix wrote:

VRP should behave as a fallback mechanism. IE, VRP should kick in when the
situation would result as an error without. Integrals literals must be typed as
integral types, so never match bool when an overload with an integral is
available (same goes for byte or short).


This is a restatement of the notion of a better match, which I've written 
about extensively in this thread.


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Walter Bright

On 4/27/2013 2:58 PM, jerro wrote:

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:

On 4/27/2013 2:29 PM, Rob T wrote:

If bools are 1 bit ints, then why do we have 'true' and 'false' as keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.


I would expect boolean literals to be something like 0b and 1b, not true and
false then.


To reiterate, history amply shows that if 'true' and 'false' are not there, then 
people will define them themselves, inconsistently, and the end result is not 
helpful to anybody.


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Walter Bright

On 4/27/2013 5:53 PM, Jonathan M Davis wrote:

which makes it so that you can define how a user-defined type will be treated
when used in a condition and for built-in types completely removes if
statements and loops from discussions on implicit conversion as there's no
implicit conversion being used (unless you're arguing for the cast to not be
inserted for conditions, in which case, implicit conversion _would_ be used).


I can't make heads or tails of this!



Re: 1 matches bool, 2 matches long

2013-04-28 Thread eles

On Sunday, 28 April 2013 at 19:19:53 UTC, Walter Bright wrote:

On 4/27/2013 2:58 PM, jerro wrote:

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright
To reiterate, history amply shows that if 'true' and 'false' 
are not there, then people will define them themselves, 
inconsistently, and the end result is not helpful to anybody.



So basically, those are to be seen as simple #defines for 0 and 1 
and nothing more than that?


I am for a boolean type that is only true and false.

And, if so much needed conversion from int 0 and int non0 to 
boolean is needed in if() and while(), then simply add ifz(), 
ifnz(), whilez() and whilenz() to the language.


(that is: ifzero(), infnonzero(), whilezero(), whilenonzero()).

This will really convey the intention of the programmer.

Elsewhere, I see no reason to accept implicit cast from bool to 
int, and less so in function overloading.


I am in favor of a true boolean type, nothing to do with 
integers, and of helpers where needed.


Besides, I do not like the idea of a bit type, because of its 
fractional representation (you need to use an entire byte for it, 
and unlike other (integer) types, its maximum range of values 
*does not* completely cover the width of its representation).


I would rather accept a ranged-type that goes from 0 to 1 
(sub-range of integers).


In Pascal that would be:

0..1, with a zero-based index


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Timon Gehr

On 04/28/2013 09:16 PM, Walter Bright wrote:

On 4/27/2013 5:53 PM, Jonathan M Davis wrote:

which makes it so that you can define how a user-defined type will be
treated
when used in a condition and for built-in types completely removes if
statements and loops from discussions on implicit conversion as
there's no
implicit conversion being used (unless you're arguing for the cast to
not be
inserted for conditions, in which case, implicit conversion _would_ be
used).


I can't make heads or tails of this!



He is saying that VRP is irrelevant in a boolean evaluation context.


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Mehrdad

On Sunday, 28 April 2013 at 19:19:53 UTC, Walter Bright wrote:

On 4/27/2013 2:58 PM, jerro wrote:
On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright 
wrote:

On 4/27/2013 2:29 PM, Rob T wrote:
If bools are 1 bit ints, then why do we have 'true' and 
'false' as keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.


I would expect boolean literals to be something like 0b and 
1b, not true and false then.


To reiterate, history amply shows that if 'true' and 'false' 
are not there, then people will define them themselves, 
inconsistently, and the end result is not helpful to anybody.



History also amply shows that having a 'bool' data type that 
tries to behave like a 'bit' data type also leads to frustration.


See:
- This thread
- std::vectorbool


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Mehrdad

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.



Walter, you've confused Boolean arithmetic with binary 
arithmetic.



Boolean arithmetic: 1 + 1 = 1
Binary  arithmetic: 1 + 1 = 0

bool means Boolean value, bit means binary integer.


The entire confusion in this thread is because you're mixing up 
the two.


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Walter Bright

On 4/28/2013 1:58 PM, Mehrdad wrote:

The entire confusion in this thread is because you're mixing up the two.


I know exactly what you're talking about, and I haven't seen any confusion from 
other posters, either.


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Mehrdad

On Sunday, 28 April 2013 at 21:17:39 UTC, Walter Bright wrote:

On 4/28/2013 1:58 PM, Mehrdad wrote:
The entire confusion in this thread is because you're mixing 
up the two.


I know exactly what you're talking about, and I haven't seen 
any confusion from other posters, either.



If I just told you why Boolean arithmetic isn't integer 
arithmetic, and you know exactly what I'm talking about, then why 
do you say Booleans are integers?


Isn't that self-contradictory?


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Timon Gehr

On 04/28/2013 10:54 PM, Mehrdad wrote:

On Sunday, 28 April 2013 at 19:19:53 UTC, Walter Bright wrote:

...

To reiterate, history amply shows that if 'true' and 'false' are not
there, then people will define them themselves, inconsistently, and
the end result is not helpful to anybody.



History also amply shows that having a 'bool' data type that tries to
behave like a 'bit' data type also leads to frustration.

See:
- This thread


History.


- std::vectorbool


The issues surrounding vectorbool are entirely unrelated.


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Timon Gehr

On 04/28/2013 11:22 PM, Mehrdad wrote:

On Sunday, 28 April 2013 at 21:17:39 UTC, Walter Bright wrote:

On 4/28/2013 1:58 PM, Mehrdad wrote:

The entire confusion in this thread is because you're mixing up the two.


I know exactly what you're talking about, and I haven't seen any
confusion from other posters, either.



If I just told you why Boolean arithmetic isn't integer arithmetic, and
you know exactly what I'm talking about, then why do you say Booleans
are integers?

Isn't that self-contradictory?


He is saying bool is an integral type in D. (i.e. it can be promoted to 
'int' in order to support integer arithmetic.)


Re: 1 matches bool, 2 matches long

2013-04-28 Thread kenji hara
Yes, as Andrei mentioned, it is sometimes useful. But, at least during
overload resolution, it must not occur.

Kenji Hara


2013/4/29 Timon Gehr timon.g...@gmx.ch

 On 04/28/2013 11:22 PM, Mehrdad wrote:

 On Sunday, 28 April 2013 at 21:17:39 UTC, Walter Bright wrote:

 On 4/28/2013 1:58 PM, Mehrdad wrote:

 The entire confusion in this thread is because you're mixing up the two.


 I know exactly what you're talking about, and I haven't seen any
 confusion from other posters, either.



 If I just told you why Boolean arithmetic isn't integer arithmetic, and
 you know exactly what I'm talking about, then why do you say Booleans
 are integers?

 Isn't that self-contradictory?


 He is saying bool is an integral type in D. (i.e. it can be promoted to
 'int' in order to support integer arithmetic.)



Re: 1 matches bool, 2 matches long

2013-04-28 Thread Mehrdad

On Sunday, 28 April 2013 at 21:29:06 UTC, Timon Gehr wrote:

On 04/28/2013 10:54 PM, Mehrdad wrote:

- std::vectorbool


The issues surrounding vectorbool are entirely unrelated.



Huh? It's entirely related.
The fact that sizeof(bool) * 8 != sizeof(byte) is what causes 
problems in vectorbool (can't treat them like other types, 
which we can address directly), and it's also one of the 
asymmetries bool has with integers in D (and any other language).


Different situation, same cause: bool doesn't behave like an 
integer.




Isn't that self-contradictory?


He is saying bool is an integral type in D. (i.e. it can be 
promoted to

'int' in order to support integer arithmetic.)

I thought we just established that boolean logic isn't integer 
logic?


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Timon Gehr

On 04/28/2013 11:51 PM, Mehrdad wrote:

On Sunday, 28 April 2013 at 21:29:06 UTC, Timon Gehr wrote:

On 04/28/2013 10:54 PM, Mehrdad wrote:

- std::vectorbool


The issues surrounding vectorbool are entirely unrelated.



Huh? It's entirely related.
The fact that sizeof(bool) * 8 != sizeof(byte) is what causes problems
in vectorbool


Exactly. This is not the problem here.


(can't treat them like other types, which we can address
directly), and it's also one of the asymmetries bool has with integers
in D (and any other language).

Different situation, same cause: bool doesn't behave like an integer.



The issue discussed here is that some think it behaves too much like an 
integer.





Isn't that self-contradictory?



He is saying bool is an integral type in D. (i.e. it can be promoted to

'int' in order to support integer arithmetic.)

I thought we just established that boolean logic isn't integer logic?


Please make sure your statements make sense.



Re: 1 matches bool, 2 matches long

2013-04-28 Thread Andrei Alexandrescu

On 4/28/13 5:41 PM, kenji hara wrote:

Yes, as Andrei mentioned, it is sometimes useful. But, at least during
overload resolution, it must not occur.

Kenji Hara


Well the problem has other ramifications beyond bool. Consider:

import std.stdio;

int fun(short v1) { return 1; }
int fun(long v1) { return 2; }

void main(string[] args)
{
writeln(fun(10_000));
writeln(fun(100_000));
}

This prints 1 2. So the behavior of bool in this case is consistent 
with the behavior of other integral types.



Andrei


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Minas Mina
On Sunday, 28 April 2013 at 22:40:33 UTC, Andrei Alexandrescu 
wrote:

On 4/28/13 5:41 PM, kenji hara wrote:
Yes, as Andrei mentioned, it is sometimes useful. But, at 
least during

overload resolution, it must not occur.

Kenji Hara


Well the problem has other ramifications beyond bool. Consider:

import std.stdio;

int fun(short v1) { return 1; }
int fun(long v1) { return 2; }

void main(string[] args)
{
writeln(fun(10_000));
writeln(fun(100_000));
}

This prints 1 2. So the behavior of bool in this case is 
consistent with the behavior of other integral types.



Andrei


It's not entirely the same. You provided two overloads of 
integral types. bool is not integral.


And yes, I personally don't like this either, but I could live 
with it. Buy fun(1) calling the bool overload? It's ridiculous.


Code that looks correct should be correct. fun(1) calling bool 
overload sure looks and is correct.


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Mehrdad

On Sunday, 28 April 2013 at 22:25:43 UTC, Timon Gehr wrote:

On 04/28/2013 11:51 PM, Mehrdad wrote:

On Sunday, 28 April 2013 at 21:29:06 UTC, Timon Gehr wrote:

On 04/28/2013 10:54 PM, Mehrdad wrote:

Isn't that self-contradictory?


He is saying bool is an integral type in D. (i.e. it can be 
promoted to 'int' in order to support integer arithmetic.)


I thought we just established that boolean logic isn't integer 
logic?


Please make sure your statements make sense.



Huh?

Walter says bool is an integer, but he understands that boolean 
variables don't follow integer logic.


That makes no sense, it's like saying I understand the sky is 
blue, but the sky is red.




What part of this is not making sense to you?


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Mehrdad
On Sunday, 28 April 2013 at 22:40:33 UTC, Andrei Alexandrescu 
wrote:

int fun(short v1) { return 1; }
int fun(long v1) { return 2; }
So the behavior of bool in this case is consistent with the 
behavior of other integral types.



We all understand that, but in that case, it's the programmer's 
fault (or intention!) for giving different behavior between the 
two.


In the bool/long case, the programmer is writing perfectly 
logical code, and it's the compiler that interprets it a weird 
way.


You can see the difference more clearly here:

void print(long a, bool newline = false)
{
write(a);
if (newline)
writeln();
}

void print(bool newline = false)
{
if (newline)
writeln();
}

void main()
{
print(1);
print(2);
}


Are you really going to blame the programmer for expecting this 
to print


1
2

or are you going to blame the language for not doing so?


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Timon Gehr

On 04/29/2013 12:51 AM, Mehrdad wrote:

On Sunday, 28 April 2013 at 22:25:43 UTC, Timon Gehr wrote:

On 04/28/2013 11:51 PM, Mehrdad wrote:

On Sunday, 28 April 2013 at 21:29:06 UTC, Timon Gehr wrote:

On 04/28/2013 10:54 PM, Mehrdad wrote:

Isn't that self-contradictory?



He is saying bool is an integral type in D. (i.e. it can be promoted
to 'int' in order to support integer arithmetic.)


I thought we just established that boolean logic isn't integer logic?


Please make sure your statements make sense.



Huh?

Walter says bool is an integer,


Certainly not. bool is a type. 2 is an integer.

He says that bool is an integral type (which has a very specific 
meaning, lined out above.)



but he understands that boolean variables don't follow integer logic.

That makes no sense, it's like saying I understand the sky is blue, but
the sky is red.



Check his statements again, I guess.



What part of this is not making sense to you?


Eg. integer logic.


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Mehrdad

On Sunday, 28 April 2013 at 23:11:50 UTC, Timon Gehr wrote:

On 04/29/2013 12:51 AM, Mehrdad wrote:

On Sunday, 28 April 2013 at 22:25:43 UTC, Timon Gehr wrote:

On 04/28/2013 11:51 PM, Mehrdad wrote:

On Sunday, 28 April 2013 at 21:29:06 UTC, Timon Gehr wrote:

On 04/28/2013 10:54 PM, Mehrdad wrote:

Isn't that self-contradictory?


He is saying bool is an integral type in D. (i.e. it can be 
promoted

to 'int' in order to support integer arithmetic.)


I thought we just established that boolean logic isn't 
integer logic?


Please make sure your statements make sense.



Huh?

Walter says bool is an integer,


Certainly not. bool is a type. 2 is an integer.


Sheesh, s/bool/a bool/.


He says that bool is an integral type (which has a very 
specific meaning, lined out above.)


o__O why would he waste time commenting on how D _behaves_?
Isn't the whole point of the discussion to figure out how D 
_should_ behave?



It's not like we haven't understood what the compiler is doing!



Eg. integer logic.


Integer logic: 1 + 1 = 2 = 0 (mod 2)
Boolean logic: 1 + 1 = 1 = 1


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Andrei Alexandrescu

On 4/28/13 6:47 PM, Minas Mina wrote:

It's not entirely the same. You provided two overloads of integral
types. bool is not integral.


Well that's what I was saying - it's consistent in the approach that 
tries to align bool with a 1-bit integral as much as possible.


Andrei


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Andrei Alexandrescu

On 4/28/13 7:19 PM, Mehrdad wrote:

Integer logic: 1 + 1 = 2 = 0 (mod 2)
Boolean logic: 1 + 1 = 1 = 1


Well D doesn't implement Boolean operators for + and *. Instead, one 
would need to use | and  respectively. When + and * are used with bool, 
promotion to int happens.


I think it's safe to assume D will never implement the Boolean meaning 
of + and *.



Andrei


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Mehrdad
On Sunday, 28 April 2013 at 23:37:23 UTC, Andrei Alexandrescu 
wrote:

On 4/28/13 7:19 PM, Mehrdad wrote:

Integer logic: 1 + 1 = 2 = 0 (mod 2)
Boolean logic: 1 + 1 = 1 = 1


Well D doesn't implement Boolean operators for + and *. 
Instead, one would need to use | and  respectively.When + and 
* are used with bool, promotion to int happens.


I think it's safe to assume D will never implement the Boolean 
meaning of + and *.



Sure. But when bool behaves only halfway like an integer (why 
doesn't it truncate when casting?) and it _also_ will never 
implement Boolean algebra with + and * (which is fine by me, I 
never requested that it does) then it should fix _one_ of those 
two aspects of itself in order to be self-consistent.


We threw out the Boolean algebra fix, so the only choice is to 
either make it behave entirely like an integer, or to make it be 
a completely different type.


In other words, we need to either:

1. Make int-bool truncate, or
2. Stop allowing implicit bool-int conversions (explicit 
conversions like in if/while/etc. are of course not included here)


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Mehrdad

On Sunday, 28 April 2013 at 23:47:20 UTC, Mehrdad wrote:

2. Stop allowing implicit bool-int conversions



And implicit int-bool as well, forgot to mention that.


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Jonathan M Davis
On Sunday, April 28, 2013 12:16:58 Walter Bright wrote:
 On 4/27/2013 5:53 PM, Jonathan M Davis wrote:
  which makes it so that you can define how a user-defined type will be
  treated when used in a condition and for built-in types completely
  removes if statements and loops from discussions on implicit conversion
  as there's no implicit conversion being used (unless you're arguing for
  the cast to not be inserted for conditions, in which case, implicit
  conversion _would_ be used).
 I can't make heads or tails of this!

I mean that if conditions and loop conditions have nothing to do with implicit 
conversions, because an explicit cast is inserted for them by the compiler. 
So, if you're discussing implicit conversions, conditions really have nothing 
to do with what's being discussed - _unless_ you're arguing that if statements 
and loops should use an implicit conversion instead of inserting an explicit 
cast. The poster I was replying to was lumping in examples of if conditions 
and loop conditions with examples of implicit conversions.

- Jonathan M Davis


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Andrei Alexandrescu

On 4/28/13 7:47 PM, Mehrdad wrote:

In other words, we need to either:

1. Make int-bool truncate, or


Not going to happen.


2. Stop allowing implicit bool-int conversions (explicit conversions
like in if/while/etc. are of course not included here)


Unlikely to ever happen.


And implicit int-bool as well, forgot to mention that.


That may have a chance.


Andrie


Re: 1 matches bool, 2 matches long

2013-04-28 Thread Walter Bright

On 4/28/2013 5:19 PM, Jonathan M Davis wrote:

I mean that if conditions and loop conditions have nothing to do with implicit
conversions, because an explicit cast is inserted for them by the compiler.
So, if you're discussing implicit conversions, conditions really have nothing
to do with what's being discussed - _unless_ you're arguing that if statements
and loops should use an implicit conversion instead of inserting an explicit
cast. The poster I was replying to was lumping in examples of if conditions
and loop conditions with examples of implicit conversions.


Ok, that's better!



Re: 1 matches bool, 2 matches long

2013-04-28 Thread Mehrdad
On Monday, 29 April 2013 at 00:40:08 UTC, Andrei Alexandrescu 
wrote:
2. Stop allowing implicit bool-int conversions (explicit 
conversions like in if/while/etc. are of course not included 
here)


Unlikely to ever happen.


What's the use case against it?


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Steven Schveighoffer
On Thu, 25 Apr 2013 23:01:30 -0700, Walter Bright  
newshou...@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


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Mehrdad

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


Re: 1 matches bool, 2 matches long

2013-04-27 Thread deadalnix

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.mitrov...@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(3);  // 1
 foo(false ? 4 : 3);  // 2
}


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


Re: 1 matches bool, 2 matches long

2013-04-27 Thread deadalnix

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
bool b = false;// ok
bool c = 1; // error, no implicit conversion
bool c = getInt();// error? ok?


Last 2 are error.


int x = 42;
if(x) { ... }   // ok (doesn't this imply c = 
getInt() ok too?

if(42) { ... } // ok


if insert a cast already, so all are ok.


Re: 1 matches bool, 2 matches long

2013-04-27 Thread khurshid

On Friday, 26 April 2013 at 18:22:10 UTC, Walter Bright wrote:

On 4/26/2013 6:51 AM, deadalnix wrote:
The last time I experienced that feature was with a char 
getting casted to bool
implicitly and then appended to a string, causing super weird 
behavior after

when using the resulting (corrupted) string.



void main()
{
bool b = 'c';
}

dmd -c foo
foo.d(4): Error: cannot implicitly convert expression ('c') of 
type char to bool

import std.stdio;

void main()
{
bool c0 = '\1'; //compiled OK
bool c1 = '\0'; //compiled OK

writeln(c0,' ',c1); //output: true false
}



Re: 1 matches bool, 2 matches long

2013-04-27 Thread kenji hara
First, I can guess that why Walter disagree *fixing* this problem.

http://dlang.org/overview.html
 Major Design Goals of D
 9. Where D code looks the same as C code, have it either behave the same
or issue an error.

Based on the design goal, we should not change the behavior toward foo(1)
matching to long version.
It will change the code behavior that looks like C.

But, we can raise an ambiguous error for the case.
I think we need to add a special rule for more natural overload
resolution in D.

// The expected behavior we can do at the most
extern(C) int printf(const char*, ...);
void foo(bool) { printf(bool\n); }
void foo(long) { printf(long\n); }
void main()
{
  foo(0);  // Error: function foo called with argument types: (int) matches
both foo(bool) and foo(long)
  foo(1);  // Error: function foo called with argument types: (int) matches
both foo(bool) and foo(long)
  foo(2);  // OK, matches to long
}

Kenji Hara

2013/4/27 Walter Bright newshou...@digitalmars.com

 On 4/26/2013 1:59 PM, Andrej Mitrovic wrote:

 On 4/26/13, Andrej Mitrovic andrej.mitrov...@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(3);  // 1
  foo(false ? 4 : 3);  // 2
 }



Re: 1 matches bool, 2 matches long

2013-04-27 Thread Andrej Mitrovic
On 4/27/13, kenji hara k.hara...@gmail.com wrote:
 // The expected behavior we can do at the most
 extern(C) int printf(const char*, ...);
 void foo(bool) { printf(bool\n); }
 void foo(long) { printf(long\n); }
 void main()
 {
   foo(0);  // Error: function foo called with argument types: (int) matches
 both foo(bool) and foo(long)
   foo(1);  // Error: function foo called with argument types: (int) matches
 both foo(bool) and foo(long)
   foo(2);  // OK, matches to long
 }

That's even more stupid. We need *less* special cases, not more. We
already have true/false, they're keywords, any other integral literal
(*literal*, not expression) should not implicitly convert to bool.


Re: 1 matches bool, 2 matches long

2013-04-27 Thread bearophile

Andrej Mitrovic:


That's even more stupid.


Please be gentle. That from Kenji is one of the few usable ideas 
of this thread.


Bye,
bearophile


Re: 1 matches bool, 2 matches long

2013-04-27 Thread deadalnix

On Saturday, 27 April 2013 at 12:20:00 UTC, bearophile wrote:

Andrej Mitrovic:


That's even more stupid.


Please be gentle. That from Kenji is one of the few usable 
ideas of this thread.


Bye,
bearophile


No, that is even worse.


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Minas Mina

On Saturday, 27 April 2013 at 11:41:30 UTC, kenji hara wrote:
First, I can guess that why Walter disagree *fixing* this 
problem.


http://dlang.org/overview.html

Major Design Goals of D
9. Where D code looks the same as C code, have it either 
behave the same

or issue an error.



C doesn't have a bool type, so how can D behave the same?


Re: 1 matches bool, 2 matches long

2013-04-27 Thread kenji hara
OK. I misunderstood.

C does not allow function overloading, so same problem is not there.
In C++,

// test.cpp
#include stdio.h
void foo(bool) { printf(bool\n); }
void foo(long) { printf(long\n); }
int main(int argc, char **argv)
{
foo(false);  // matches bool version
foo(true);   // matches bool version
foo(0);  // ambiguous
foo(1);  // ambiguous
foo(2);  // ambiguous
return 0;
}

The behavior is same with GCC 4.7.2 (using msys) and dmc.

Walter, now I changed my opinion. It seems not correct that being regarded
bool type as one of the integer.
How about?

Kenji Hara

2013/4/27 Minas Mina minas_mina1...@hotmail.co.uk

 On Saturday, 27 April 2013 at 11:41:30 UTC, kenji hara wrote:

 First, I can guess that why Walter disagree *fixing* this problem.

 http://dlang.org/overview.html

 Major Design Goals of D
 9. Where D code looks the same as C code, have it either behave the same

 or issue an error.


 C doesn't have a bool type, so how can D behave the same?



Re: 1 matches bool, 2 matches long

2013-04-27 Thread Diggory

On Saturday, 27 April 2013 at 10:17:58 UTC, deadalnix wrote:

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.mitrov...@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(3);  // 1
foo(false ? 4 : 3);  // 2
}


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


I agree 100% VRP is nice but it should not be used implicitly to 
resolve ambiguous cases, that definitely goes against least 
surprise and all that.


Re: 1 matches bool, 2 matches long

2013-04-27 Thread MattCoder
One of the main problem that I saw here, is this behavior (DMD 
2.062):


import std.stdio;

void foo(bool b) { writeln(bool); }
void foo(long l) { writeln(long); }

void main()
{
int num = 0;

foo(num);
foo(0);
foo(2);
}

output:
long
bool
long

As num = 0, for me both: foo(num) and foo(0) should give the 
same output (long), regardless that num is integer implicit 
declaration or not.


Re: 1 matches bool, 2 matches long

2013-04-27 Thread kenji hara
I filed the issue in bugzilla, and opened pull request to fix it.

http://d.puremagic.com/issues/show_bug.cgi?id=
https://github.com/D-Programming-Language/dmd/pull/1942

Kenji Hara


2013/4/28 kenji hara k.hara...@gmail.com

 OK. I misunderstood.

 C does not allow function overloading, so same problem is not there.
 In C++,

 // test.cpp
 #include stdio.h
 void foo(bool) { printf(bool\n); }
 void foo(long) { printf(long\n); }
 int main(int argc, char **argv)
 {
 foo(false);  // matches bool version
 foo(true);   // matches bool version
  foo(0);  // ambiguous
 foo(1);  // ambiguous
  foo(2);  // ambiguous
 return 0;
 }

 The behavior is same with GCC 4.7.2 (using msys) and dmc.

 Walter, now I changed my opinion. It seems not correct that being regarded
 bool type as one of the integer.
 How about?

 Kenji Hara

 2013/4/27 Minas Mina minas_mina1...@hotmail.co.uk

 On Saturday, 27 April 2013 at 11:41:30 UTC, kenji hara wrote:

 First, I can guess that why Walter disagree *fixing* this problem.

 http://dlang.org/overview.html

 Major Design Goals of D
 9. Where D code looks the same as C code, have it either behave the same

 or issue an error.


 C doesn't have a bool type, so how can D behave the same?





Re: 1 matches bool, 2 matches long

2013-04-27 Thread Walter Bright

On 4/26/2013 7:36 PM, Mehrdad wrote:

Walter, you're completely missing the point.


I completely understand it is a perception problem. Some people see bool as a 1 
bit integer (including me). Some see bool as something very distinct from 
integers (including you).


An analogous issue comes up here now and then about 'char' and characters. Are 
chars an 8 byte integer, or are they characters, or are they octets, or should 
access only be allowed to multibyte characters as an indivisible code point? 
(This comes up in regards to indexing char[].)




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.


What I find distressing about these kinds of threads is how people dig in and so 
fortify their position on a rather trivial matter and then it blows up into some 
do-or-die thing.




Re: 1 matches bool, 2 matches long

2013-04-27 Thread Walter Bright

On 4/26/2013 5:14 PM, H. S. Teoh wrote:

Does VRP work only with literals, or does it work with general variables
(by inferring from, say, if-conditions)?

void func(int i) {
ubyte b;
if (i = 0  i  256) {
b = i;  // OK without cast?
}
...
}


Such would require data flow analysis, which is beyond the scope of what the 
front end is designed to do. So, no, for the foreseeable future.




Re: 1 matches bool, 2 matches long

2013-04-27 Thread Walter Bright

On 4/26/2013 9:19 PM, Maxim Fomin wrote:

Then perhaps ban VRP on arguments if it affects overloading?


That'll just make another group of people unhappy.

It's like designing a house with a fixed footprint. You can make the kitchen 
larger and the bathroom smaller, or vice versa, but you can't make them both bigger.


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Walter Bright

On 4/27/2013 8:11 AM, kenji hara wrote:

Walter, now I changed my opinion. It seems not correct that being regarded bool
type as one of the integer.
How about?


Both C and C++ regard bool as an integer, and implicitly convert 1/0 to 
true/false.

What C++ doesn't have is VRP and partial ordering of functions. (But it does 
have partial ordering of template functions.)


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Walter Bright

On 4/26/2013 3:28 PM, Jonathan M Davis wrote:

Sure, it may be useful sometimes to have code that treats true as 1 and false
as 0 for math, but I'd argue for casting being required for it, and in a large
number of cases, casting would be required already due to the fact that it
would be a narrowing conversion. But it seems very wrong to me that foo(1)
would call a bool overload or that foo ~ true would compile.


It's not any different from how char is treated (char is also treated as an 
integer type).




There have been
a number of posts over time discussing bugs caused by that behavior being
legal. I don't think that it's a huge problem, but I do think that it's a
problem.


In general, D treats bool, char, wchar, and dchar as integer types. D also 
follows the C practice of unadorned integer literals being typed as ints, and 
the C practice of default integral promotions.


If you're not aware of this, yes, you can get surprised when working with 
overloads across those types.


The solution in the antecedent's particular case is to add an overload foo(int), 
which will neatly prevent any unadorned integer literals from being implicitly 
cast to char or bool or whatever. It's also a good practice in that 
unnecessarily promoting ints to longs is a bit of an efficiency issue.


[Generally, I'd raise a red flag on any code that only provided foo(bool) and 
foo(long) overloads.]




However, we are clearly coming from very different points of view
here.


Thanks for understanding my point that this is not a right or wrong issue, but a 
matter of perspective.




Re: 1 matches bool, 2 matches long

2013-04-27 Thread kenji hara
2013/4/28 Walter Bright newshou...@digitalmars.com

 On 4/27/2013 8:11 AM, kenji hara wrote:

 Walter, now I changed my opinion. It seems not correct that being
 regarded bool
 type as one of the integer.
 How about?


 Both C and C++ regard bool as an integer, and implicitly convert 1/0 to
 true/false.

 What C++ doesn't have is VRP and partial ordering of functions. (But it
 does have partial ordering of template functions.)


I'm not argue that we should remove the implicit conversion from 1/0 to
bool.

I don't have so much knowledge about C/C++ language spec, but for the issue
case C++ makes ambiguous error.
Contrary of that, D's current behavior looks to me it is going back to past.

Kenji Hara


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Walter Bright

On 4/26/2013 11:04 PM, Steven Schveighoffer wrote:

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.


The overload system in D is explicitly not based on better. (The C++ better 
overloading system is for functions, but not for templates.) The D overload 
system is based on partial ordering, which is the same as what C++ uses for 
templates.


I don't know for a fact, but I'm pretty sure the partial ordering scheme that 
C++ selected for templates, which came along many years later, was picked 
because people realized it was better (and more mathematically robust and 
defensible).


One of the problems with a better matching system is handling functions with 
multiple parameters, each with their own better match. (The C++ Standard 
devotes a great deal of complex text to this, it boils down to a bunch of rather 
arbitrary decisions.) Partial ordering solves this neatly and consistently.


As one who implemented C++'s better matching system, I can confidently state 
that the partial ordering scheme is FAR better overall.


Re: 1 matches bool, 2 matches long

2013-04-27 Thread kenji hara
(This is a quotation from
http://d.puremagic.com/issues/show_bug.cgi?id=http://d.puremagic.com/issues/show_bug.cgi?id=#c4
)

 I do not agree with this enhancement. First off, making special cases for
 partial ordering takes a simple, straightforward idea and turns it into a
 potential morass of conflicting cases that we'll be stuck with forever.
 Secondly, the only issue here is whether '1' should be implicitly
convertible
 to 'bool'.

Walter, I can understand your concern. But I think it would not be so big.
Because the possibility of extending basic type set is not so much in the
future.

Keeping language spec simple is necessary, but also reduce special rule for
humans is also important. This is a much rare case that is the mismatch
between
simple rule and natural behavior for human. Fixing this issue would be
valuable
for many D users.

Logically 'true' and  'false' are not related to any integer values.
Although
it is widely known and used, considering boolean type as a kind of
specialized
integer type is not general - it is implementation detail. At least it comes
from C language. In old ages, boolean type had not been supported properly
in
many programming languages, but today, languages which not supporting it
would
not regarded as useful. D is a modern programming language, so more proper
behavior for boolean type is necessary.

As one of its goal, D should aim the successor of C. Therefore, we cannot
drop
the implicit conversion between bool and other integer types which inherited
from C.
But this problem behavior is definitely unnatural for many programmers, and
would enforce to study bad know-how for them. Loosing future users for the
compiler simplicity is not good decision. Of course, balance is necessary
there, but I think this is necessary complexity.

Kenji Hara


2013/4/28 kenji hara k.hara...@gmail.com

 2013/4/28 Walter Bright newshou...@digitalmars.com

 On 4/27/2013 8:11 AM, kenji hara wrote:

 Walter, now I changed my opinion. It seems not correct that being
 regarded bool
 type as one of the integer.
 How about?


 Both C and C++ regard bool as an integer, and implicitly convert 1/0 to
 true/false.

 What C++ doesn't have is VRP and partial ordering of functions. (But it
 does have partial ordering of template functions.)


 I'm not argue that we should remove the implicit conversion from 1/0 to
 bool.

 I don't have so much knowledge about C/C++ language spec, but for the
 issue case C++ makes ambiguous error.
 Contrary of that, D's current behavior looks to me it is going back to
 past.

 Kenji Hara



Re: 1 matches bool, 2 matches long

2013-04-27 Thread Mehrdad

On Saturday, 27 April 2013 at 19:51:48 UTC, Walter Bright wrote:

On 4/26/2013 7:36 PM, Mehrdad wrote:

Walter, you're completely missing the point.


I completely understand it is a perception problem. Some people 
see bool as a 1 bit integer (including me). Some see bool as 
something very distinct from integers (including you).



The problem is 'bool' has *NOTHING* in common with integers!

- Can't use + - * /   on bool's
- (bool)2 == (bool)1  (do you SERIOUSLY think this is 
integer-like?)

- sizeof(int64) == 8 * sizeof(int8)
- sizeof(int8 ) != 8 * sizeof(bool)


There is literally _NOTHING_ about bool that's integer-like, and 
for some reason you still think bool is an integer.


And you still wonder why people find D frustrating?


An analogous issue comes up here now and then about 'char' and 
characters.


That was a C++ mistake, I hope you're not trying to repeat it.

Heck, even in C++, you can make sense out of it if you stick with 
the convention:


- char == character
- unsigned char == ubyte
- signed char == sbyte


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Rob T

On Saturday, 27 April 2013 at 20:31:15 UTC, Mehrdad wrote:

The problem is 'bool' has *NOTHING* in common with integers!

- Can't use + - * /   on bool's


Because currently D views booleans as a 1 bit int, you can do 
seemingly nonsensical things with the bool type


bool b = false + true; // OK
bool b = true * true; // OK
bool b = true / true; // OK
bool b = true + true; // compile error because 2 does not fit 
into 1 bit.


Even if you accept the view that bool is a 1 bit int, this 
conditional makes no sense at all


int x = -123456;
if (x) then
{
   // evaluates to true, but why???
}

if (x == true) then
{
   // false because x != true(1), even though previously it was 
true

}

If bools are 1 bit ints, then why do we have 'true' and 'false' 
as keywords? Those keywords only serve to confuse the programmer 
into thinking that the bool type is actually a real boolean type.


The worse thing about this situation is the inconsistencies. It 
would not be nearly as bad if bool really was a 1 bit int type, 
instead it sometimes behaves like an int and sometimes it behaves 
like a boolean. Why name name the type bool instead of bit? 
Why have true and false keywords?


What I gather from the state of affairs, is an attempt to create 
the illusion of a boolean while retaining all of the properties 
of a 1 bit int type, with the notable exception of the weird 
conditional that evaluates an integer to true if it is not 0.


--rt


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Rob T

On Saturday, 27 April 2013 at 19:51:48 UTC, Walter Bright wrote:
An analogous issue comes up here now and then about 'char' and 
characters. Are chars an 8 byte integer, or are they 
characters, or are they octets, or should access only be 
allowed to multibyte characters as an indivisible code point? 
(This comes up in regards to indexing char[].)


The real problem I think is caused by trying to fit two 
conceptually different things into the same container and then 
merging the two conceptually different behaviors together. It's 
very confusing and causes unexpected conflicts.


My analogy is having two exactly identical containers labeled 
water, but use one to store water and the other gasoline, then 
wait until someone yells fire!.


To solve the char problem, what should be done, is have a real 
'char' type and a real 'byte' type to settle the matter, and use 
explicit casting where required.


To transform bool into something sensible that we can all agree 
with, there should a a 'bool' type and a 'bit' type, and use 
explicit casting where required.


What we have instead is a confounding merging of dissimilar 
containers for  conflicting purposes. This is completely 
avoidable and easily so.


--rt


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Minas Mina

VRP is only useful when doing this:

short s = 1000; // 1000 is int, but it's safe to put it into a 
short


Integers are not booleans. I agree with the others that bool 
being treated as an int is an implementation detail derived from 
C.


Or are you just bored for doing:
if( x == 0 )

instead of
if( x )

?


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Walter Bright

On 4/27/2013 2:29 PM, Rob T wrote:

If bools are 1 bit ints, then why do we have 'true' and 'false' as keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.



Re: 1 matches bool, 2 matches long

2013-04-27 Thread jerro

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:

On 4/27/2013 2:29 PM, Rob T wrote:
If bools are 1 bit ints, then why do we have 'true' and 
'false' as keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.


I would expect boolean literals to be something like 0b and 1b, 
not true and false then.


Re: 1 matches bool, 2 matches long

2013-04-27 Thread eles

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:

On 4/27/2013 2:29 PM, Rob T wrote:
Because writing cast(bool)0 and cast(bool)1 is unappealing.


why need to write that? just drop the bool type entirely and go 
ahead with an integer that you interpret as a boolean.


welcome back to C (kr).


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Mehrdad

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:

On 4/27/2013 2:29 PM, Rob T wrote:
If bools are 1 bit ints, then why do we have 'true' and 
'false' as keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.



Unappealing to whom?


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Rob T

On Saturday, 27 April 2013 at 21:59:50 UTC, eles wrote:

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:

On 4/27/2013 2:29 PM, Rob T wrote:
Because writing cast(bool)0 and cast(bool)1 is unappealing.


why need to write that? just drop the bool type entirely and go 
ahead with an integer that you interpret as a boolean.


The problem is that Walter appears to want the convenience of a 
real bool type, but also the convenience of a real bit type, all 
merged together into one container that is confusingly labeled as 
'bool'.


See my previous post about the problems caused when merging two 
conceptually different things into one container and then make it 
appear as if it stores only one of the conceptually different 
things - sometimes. Thats never a good idea.


We can solve the problem by defining a real boolean type and a 
real bit type and allow explicit casting if required (which 
should be rare).


--rt


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Paulo Pinto

Am 27.04.2013 23:52, schrieb Walter Bright:

On 4/27/2013 2:29 PM, Rob T wrote:

If bools are 1 bit ints, then why do we have 'true' and 'false' as
keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.



No, this brings us back into the realm of C and weak type checking.


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Namespace
If bools are 1 bit ints, then why do we have 'true' and 'false' 
as keywords? Those keywords only serve to confuse the 
programmer into thinking that the bool type is actually a real 
boolean type.


C++ has also true and false and they are converted to integers by 
the compiler.


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Rob T

On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:

On 4/27/2013 2:29 PM, Rob T wrote:
If bools are 1 bit ints, then why do we have 'true' and 
'false' as keywords?


Because writing cast(bool)0 and cast(bool)1 is unappealing.


That cannot be the main reason. There must be a more fundamental 
reason for having true and false (which is inconsistent with 
ints) instead of 1b and 0b (which is consistent with ints).


--rt


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Walter Bright

On 4/27/2013 1:26 PM, kenji hara wrote:

I don't have so much knowledge about C/C++ language spec, but for the issue case
C++ makes ambiguous error.


That's because C++ regards an implicit conversion of 1 to bool or long as having 
equal weight, and it has no further mechanism.




Re: 1 matches bool, 2 matches long

2013-04-27 Thread Walter Bright

On 4/27/2013 3:58 PM, Walter Bright wrote:

On 4/27/2013 1:26 PM, kenji hara wrote:

I don't have so much knowledge about C/C++ language spec, but for the issue case
C++ makes ambiguous error.


That's because C++ regards an implicit conversion of 1 to bool or long as having
equal weight, and it has no further mechanism.



Note that the following is also ambiguous in C++:

void foo(bool b) { }
void foo(long l) { }

void main() {
foo(3);
}


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Jonathan M Davis
On Saturday, April 27, 2013 14:52:31 Walter Bright wrote:
 On 4/27/2013 2:29 PM, Rob T wrote:
  If bools are 1 bit ints, then why do we have 'true' and 'false' as
  keywords?
 Because writing cast(bool)0 and cast(bool)1 is unappealing.

You'd only be forced to do that outside of conditions, as the cast is already 
inserted for you in conditions. And if you really need bool, one could argue 
that it doesn't make sense to be using integer literals anyway. We already 
have true and false if you really want a bool when deal with literals. I like 
being able to do while(1) because it's shorter, but it's not ultimately all 
that onerous to have to do while(true), and the casting in conditions takes 
care of that case anyway. In most cases, simply using a bool when you mean 
bool, and an int when you want an integral type solves the problem quite 
cleanly.

The main place that I can see that it makes sense to end up with casts to and 
from bool which might get annoying is if you're trying to use bools in 
arithmetic, and I honestly don't think that allowing implicit casts there is 
worth all of the other weirdness it causes in the language in general.

- Jonathan M Davis


Re: 1 matches bool, 2 matches long

2013-04-27 Thread Jonathan M Davis
On Saturday, April 27, 2013 06:19:29 Maxim Fomin wrote:
 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?

No. The problem really isn't with VRP. The problem is the fact that D is 
weakly typed with regards to bool. In virtually all cases, having VRP do it's 
job is exactly what we want. It's just that in this one, weird things happen 
because of the implicit conversion to bool which is of zero utility in this 
case, because if that's what you wanted, you'd just use a boolean literal 
rather than an integer one.

I really think that allowing the implicit conversion to bool is truly helpful 
in only a small number of cases (e.g. arithmetic which wants to add 0 or 1 
depending on the result of a boolean expression), and it clearly results in 
behavior that most people don't expect in quite a few instances. The fact that 
stuff like

auto b = false / true;

compiles is just downright bizarre.

- Jonathan M Davis


  1   2   >