Re: 1 matches bool, 2 matches long
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
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
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
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
+1 (and give a helpful compiler error with suggested modification)
Re: 1 matches bool, 2 matches long
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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/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
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
(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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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