digitalmars.D - 1 matches bool, 2 matches long
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (31/31) Apr 25 2013 This question has first appeared on D.learn:
- Timon Gehr (5/10) Apr 25 2013 bool is more specialized than long; you can pass any bool argument as a
- Simen Kjaeraas (10/40) Apr 25 2013 re =
- Walter Bright (2/3) Apr 25 2013 Yes, because a bool can be implicitly converted to a long, but a long ca...
- deadalnix (3/6) Apr 25 2013 As we have bool literals as true and false, I don't think 1
- Jonathan M Davis (10/14) Apr 25 2013 However, given that bool isn't even an integral type, it seems very wron...
- deadalnix (3/25) Apr 25 2013 And indeed they do. I did face some very weird bugs caused by
- ixid (2/4) Apr 26 2013 What sort of bugs has it caused for you? Just interested, not
- deadalnix (7/11) Apr 26 2013 The last time I experienced that feature was with a char getting
- Walter Bright (7/10) Apr 26 2013 void main()
- khurshid (9/22) Apr 27 2013 import std.stdio;
- bearophile (4/4) Apr 25 2013 Is is acceptable for 1 to match bool and 2 long? Maybe it is not
- Maxim Fomin (6/23) Apr 25 2013 Looks like value range propagation bug because 1 is integer
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (13/19) Apr 25 2013 That special conversion rule of literal 0 and literal 1 being implicitly...
- Andrej Mitrovic (13/16) Apr 25 2013 An even better example:
- Maxim Fomin (4/17) Apr 26 2013 Sorry but I am not aware of how 1 is converted to bool here.
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (7/29) Apr 26 2013 Since the type of literal 1 is int, calling foo(long) would require an
- Andrej Mitrovic (10/11) Apr 26 2013 import std.stdio;
- Walter Bright (10/21) Apr 26 2013 How about this one:
- Rob T (8/33) Apr 26 2013 We all know that short and long are integer numerics, however
- Mehrdad (12/37) Apr 26 2013 Walter, you're completely missing the point.
- Walter Bright (11/17) Apr 27 2013 I completely understand it is a perception problem. Some people see bool...
- Mehrdad (16/23) Apr 27 2013 The problem is 'bool' has *NOTHING* in common with integers!
- Rob T (33/35) Apr 27 2013 Because currently D views booleans as a 1 bit int, you can do
- Walter Bright (2/3) Apr 27 2013 Because writing cast(bool)0 and cast(bool)1 is unappealing.
- jerro (3/7) Apr 27 2013 I would expect boolean literals to be something like 0b and 1b,
- Walter Bright (4/11) Apr 28 2013 To reiterate, history amply shows that if 'true' and 'false' are not the...
- eles (21/26) Apr 28 2013 So basically, those are to be seen as simple #defines for 0 and 1
- deadalnix (2/15) Apr 29 2013 This is plain useless as a cast is already inserted here.
- eles (2/7) Apr 29 2013 so, only allow explict casting then.
- Sean Cavanaugh (8/11) Apr 29 2013 int x = 3;
- eles (4/7) Apr 29 2013 I know, but I still think that ifz() and ifnz() convey better
- Mehrdad (6/20) Apr 28 2013 History also amply shows that having a 'bool' data type that
-
Timon Gehr
(3/14)
Apr 28 2013
The issues surrounding vector
are entirely unrelated. - Mehrdad (11/17) Apr 28 2013 Huh? It's entirely related.
- Timon Gehr (5/21) Apr 28 2013 The issue discussed here is that some think it behaves too much like an
- Mehrdad (7/18) Apr 28 2013 Huh?
- Timon Gehr (6/24) Apr 28 2013 Certainly not. bool is a type. 2 is an integer.
- Mehrdad (8/32) Apr 28 2013 o__O why would he waste time commenting on how D _behaves_?
- Andrei Alexandrescu (7/9) Apr 28 2013 Well D doesn't implement Boolean operators for + and *. Instead, one
- Mehrdad (14/22) Apr 28 2013 Sure. But when bool behaves only halfway like an integer (why
- Mehrdad (2/3) Apr 28 2013 And implicit int->bool as well, forgot to mention that.
- Andrei Alexandrescu (5/10) Apr 28 2013 Unlikely to ever happen.
- eles (4/6) Apr 27 2013 why need to write that? just drop the bool type entirely and go
- Rob T (13/18) Apr 27 2013 The problem is that Walter appears to want the convenience of a
- Mehrdad (2/6) Apr 27 2013 Unappealing to whom?
- Paulo Pinto (2/6) Apr 27 2013 No, this brings us back into the realm of C and weak type checking.
- Rob T (5/9) Apr 27 2013 That cannot be the main reason. There must be a more fundamental
- Jonathan M Davis (15/19) Apr 27 2013 You'd only be forced to do that outside of conditions, as the cast is al...
- Timon Gehr (2/4) Apr 27 2013 for(;;) is shorter.
- Jonathan M Davis (10/15) Apr 27 2013 True, but I'd never use it, because I'd never use a for loop for anythin...
- deadalnix (2/6) Apr 28 2013 VRP say you don't need to.
- deadalnix (4/11) Apr 28 2013 Which is kind o funny, because we didn't had to wait for long
- Rob T (9/16) Apr 28 2013 I was wondering who was going to notice that elephant. I didn't
- Timon Gehr (7/14) Apr 28 2013 void foo(bool b){ } // 1
- Walter Bright (5/11) Apr 28 2013 You're implying there is no need for 1L or 1U either, but there is.
- Diggory (19/34) Apr 29 2013 The same could be said of booleans. If D does not have a proper
- eles (9/21) Apr 29 2013 gdc:
- Mike James (4/12) Apr 29 2013 If you are going to create a boolean then use it as a boolean - it's not...
- Namespace (2/6) Apr 27 2013 C++ has also true and false and they are converted to integers by
- Rob T (18/23) Apr 27 2013 The real problem I think is caused by trying to fit two
- deadalnix (6/14) Apr 27 2013 Don't be silly. You don't see them as 1 bit integer, as they
- =?UTF-8?B?Ikx1w61z?= Marques" (7/9) Apr 27 2013 This corroborates Rob T's positions that the current bool type
- Steven Schveighoffer (10/15) Apr 29 2013 short x = cast(short)0x10000;
- Jonathan M Davis (5/24) Apr 29 2013 It also isn't considered to be an integral type per std.traits.isIntegra...
- deadalnix (3/28) Apr 27 2013 VRP should be used as a fallback mechanism. Yes, kill it with
- Diggory (4/37) Apr 27 2013 I agree 100% VRP is nice but it should not be used implicitly to
- kenji hara (23/53) Apr 27 2013 or issue an error.
- Minas Mina (2/9) Apr 27 2013 C doesn't have a bool type, so how can D behave the same?
- kenji hara (22/34) Apr 27 2013 OK. I misunderstood.
- MattCoder (19/19) Apr 27 2013 One of the main problem that I saw here, is this behavior (DMD
- Walter Bright (4/7) Apr 27 2013 Both C and C++ regard bool as an integer, and implicitly convert 1/0 to ...
- kenji hara (7/17) Apr 27 2013 I'm not argue that we should remove the implicit conversion from 1/0 to
- Walter Bright (3/5) Apr 27 2013 That's because C++ regards an implicit conversion of 1 to bool or long a...
- Walter Bright (7/12) Apr 27 2013 Note that the following is also ambiguous in C++:
- kenji hara (19/38) Apr 27 2013 Yes, but all C++ users would accept the behavior - In C++, all integer
- Walter Bright (4/7) Apr 28 2013 Again, whether it is "weird" or not comes from your perspective. From mi...
- deadalnix (2/12) Apr 28 2013 Then be consistent. Convert int to bool by truncating.
- Andrei Alexandrescu (66/78) Apr 28 2013 Let me start by saying that I agree with the view that this isn't a
- deadalnix (9/10) Apr 28 2013 I think you missed a point I tried to raise several time
- Walter Bright (3/7) Apr 28 2013 This is a restatement of the notion of a "better" match, which I've writ...
- Rob T (40/44) Apr 29 2013 On Sunday, 28 April 2013 at 13:38:53 UTC, Andrei Alexandrescu
- kenji hara (38/38) Apr 27 2013 A real issue against disallowing 0/1 to bool conversion is in the
- kenji hara (34/61) Apr 27 2013 (This is a quotation from
- Minas Mina (11/11) Apr 27 2013 VRP is only useful when doing this:
- kenji hara (5/41) Apr 27 2013 I filed the issue in bugzilla, and opened pull request to fix it.
- Andrej Mitrovic (4/16) Apr 27 2013 That's even more stupid. We need *less* special cases, not more. We
- bearophile (5/6) Apr 27 2013 Please be gentle. That from Kenji is one of the few usable ideas
- deadalnix (2/8) Apr 27 2013 No, that is even worse.
- Kapps (3/3) Apr 25 2013 This is just silly.
- Walter Bright (15/18) Apr 25 2013 This does:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (18/36) Apr 25 2013 It certainly behaves that way but it isn't an integer type and that's
- Walter Bright (18/31) Apr 25 2013 Whether it's a problem or not depends on one's perspective.
- deadalnix (2/6) Apr 25 2013 Yes.
- Manipulator (5/13) Apr 25 2013 +1
- Walter Bright (4/7) Apr 26 2013 Implicit conversions make the menagerie of integer types tractable. Expl...
- deadalnix (2/17) Apr 26 2013 No no no no, please no.
- Maxim Fomin (5/10) Apr 26 2013 Regarding bool type as integer type is C atavism and should be
- Walter Bright (9/12) Apr 26 2013 There's a very loooong history of 0 being regarded as false and 1 as tru...
- Maxim Fomin (8/23) Apr 26 2013 This should be irrelevant in case of long parameter. Such
- Walter Bright (6/9) Apr 26 2013 I'm sorry, but that's an assertion not an argument.
- Paulo Pinto (8/13) Apr 26 2013 Assembly, PL/I, Algol, ...? Just asking as a language geek.
- deadalnix (6/11) Apr 26 2013 That is true, but even in theses elder languages, bool is handled
- Walter Bright (8/19) Apr 26 2013 I've also spent time with embedded systems that manipulated things by wr...
- deadalnix (2/4) Apr 26 2013 Don't need to look far away. Most shell do that.
- Rob T (5/9) Apr 26 2013 D can still cast true to 1 and false to 0. It is solely the
- =?UTF-8?B?Ikx1w61z?= Marques" (9/9) Apr 26 2013 Is this what some of you are asking for?
- Mehrdad (8/17) Apr 26 2013 Yes
- deadalnix (3/12) Apr 27 2013 if insert a cast already, so all are ok.
- Jonathan M Davis (12/22) Apr 27 2013 if conditions and loop conditions automatically insert explicit casts, s...
- Walter Bright (2/7) Apr 28 2013 I can't make heads or tails of this!
- Timon Gehr (2/13) Apr 28 2013 He is saying that VRP is irrelevant in a boolean evaluation context.
- Jonathan M Davis (9/17) Apr 28 2013 I mean that if conditions and loop conditions have nothing to do with im...
- Walter Bright (2/9) Apr 28 2013 Ok, that's better!
- Minas Mina (8/13) Apr 26 2013 It is an integral type _internally_.
- Jonathan M Davis (14/25) Apr 26 2013 That was one of C's big mistakes. There's nothing whatsoever about bool ...
- Rob T (12/15) Apr 26 2013 IMO it still makes no sense to have the implicit casting done in
- Walter Bright (5/7) Apr 26 2013 This is where our perspectives sharply diverge. A bool is a 1 bit intege...
- Andrej Mitrovic (2/3) Apr 26 2013 .sizeof returns bytes, not bits, and says that bool is of size 1.
- eles (12/17) Apr 26 2013 Uh, uh, that's not a bool. It is a bit (binary digit, just to be
- Jonathan M Davis (11/21) Apr 26 2013 Sure, it may be useful sometimes to have code that treats true as 1 and ...
- Walter Bright (16/27) Apr 27 2013 It's not any different from how char is treated (char is also treated as...
- Jonathan M Davis (34/53) Apr 27 2013 Yes, but I honestly think that that's problem too. I think that there's ...
- Walter Bright (24/58) Apr 28 2013 Are you really solving a problem, or just creating new ones? I'd rather ...
- deadalnix (3/8) Apr 26 2013 Then why does it convert from int by comparing with 0 ? That
- Mehrdad (2/11) Apr 26 2013 +1
- Brian Schott (3/7) Apr 26 2013 The idea of a "true number" and a "false number" doesn't make
- Tove (15/24) Apr 26 2013 I find the current implementation perfectly intuitive and I
- eles (6/11) Apr 26 2013 I assume you are doing C or C++. Under the preprocessor, why do
- bearophile (6/10) Apr 26 2013 I think here people are not asking to disallow that. A 0 and 1
- deadalnix (3/25) Apr 26 2013 That is totally irrelevant as a cast is already inserted
- Steven Schveighoffer (20/32) Apr 26 2013 I think the issue (and I am firmly in the foo(1) => long camp) is that
- Walter Bright (15/19) Apr 27 2013 The overload system in D is explicitly not based on "better". (The C++ "...
- Steven Schveighoffer (12/35) Apr 29 2013 I think you are inventing a strawman problem that this bug solves. Ther...
- Paulo Pinto (5/44) Apr 29 2013 Fully agree, I still not understand what is the issue to support the
- Walter Bright (3/36) Apr 29 2013 Carefully reading your statement, you are still arguing that matching 1 ...
- Steven Schveighoffer (4/22) Apr 30 2013 Yes, just like it's better matching to long than string.
- Rob T (13/15) Apr 30 2013 More precise language is to state that there is no "better match"
- Steven Schveighoffer (13/28) Apr 30 2013 1. bool doesn't match to 1 or 0.
- Paulo Pinto (2/32) Apr 30 2013 +1
- Timothee Cour (1/1) Apr 30 2013 +1 (and give a helpful compiler error with suggested modification)
- MattCoder (21/38) Apr 30 2013 Walter, Don't you agree that the current way can be confusing?
- Mehrdad (8/12) Apr 28 2013 Walter, you've confused "Boolean arithmetic" with "binary
- Walter Bright (3/4) Apr 28 2013 I know exactly what you're talking about, and I haven't seen any confusi...
- Mehrdad (5/10) Apr 28 2013 If I just told you why Boolean arithmetic isn't integer
- Timon Gehr (3/13) Apr 28 2013 He is saying bool is an integral type in D. (i.e. it can be promoted to
- kenji hara (4/25) Apr 28 2013 Yes, as Andrei mentioned, it is sometimes useful. But, at least during
- Andrei Alexandrescu (13/16) Apr 28 2013 Well the problem has other ramifications beyond bool. Consider:
- Minas Mina (8/26) Apr 28 2013 It's not entirely the same. You provided two overloads of
- Andrei Alexandrescu (4/6) Apr 28 2013 Well that's what I was saying - it's consistent in the approach that
- Mehrdad (31/35) Apr 28 2013 We all understand that, but in that case, it's the programmer's
- deadalnix (3/20) Apr 29 2013 For the same reason, both should call the long overload.
- deadalnix (5/24) Apr 25 2013 This "feature" never has been useful to me. It has caused bug.
- Mehrdad (2/5) Apr 26 2013 +1
- Walter Bright (6/11) Apr 26 2013 The bug is not providing an overload for int.
- Robert Schadek (14/15) Apr 26 2013 This is True for the type but for the actual code it looks different.
- Walter Bright (3/5) Apr 26 2013 I've used a language with no implicit casts. It didn't get better, and I...
- Timon Gehr (3/8) Apr 26 2013 What language?
- Walter Bright (2/12) Apr 26 2013 An early Pascal.
- Diggory (39/39) Apr 26 2013 Whatever the choices are of whether bool is a 1-bit integer or a
- Walter Bright (32/35) Apr 26 2013 D has an interesting feature called VRP (value range propagation), where...
- Zach the Mystic (3/6) Apr 26 2013 The government of North Korea would probably be perfectly happy
- Jonathan M Davis (4/6) Apr 26 2013 VRP is a fantastic feature, but I think that it's coming back to bite us...
- H. S. Teoh (14/20) Apr 26 2013 [...]
- Walter Bright (3/12) Apr 27 2013 Such would require data flow analysis, which is beyond the scope of what...
- Maxim Fomin (2/9) Apr 26 2013 Then perhaps ban VRP on arguments if it affects overloading?
- Walter Bright (4/5) Apr 27 2013 That'll just make another group of people unhappy.
- Jonathan M Davis (15/26) Apr 27 2013 No. The problem really isn't with VRP. The problem is the fact that D is...
- Paulo Pinto (2/28) Apr 27 2013 Well, we need material to write "D the good parts" :)
This question has first appeared on D.learn: http://forum.dlang.org/post/vlosugoeuobjrdfaeegk forum.dlang.org A simple program: import std.stdio; void foo(bool b) { writeln("bool"); } void foo(long l) { writeln("long"); } void main() { foo(1); foo(2); } The program calls two separate foo() overloads for 1 and 2: bool long According to the language spec, both overloads match the int argument by "implicit conversion" as described under "Function Overloading" here: http://dlang.org/function.html Then, the overload must be resolved by partial ordering: "If two or more functions have the same match level, then partial ordering is used to try to find the best match. Partial ordering finds the most specialized function." Is bool more specialized than long or is this a bug? Intuitively, both should match the 'long' overload. It feels like there should at least be ambiguity. Ali
Apr 25 2013
On 04/25/2013 11:05 PM, Ali Çehreli wrote:... Is bool more specialized than long or is this a bug? Intuitively, both should match the 'long' overload.bool is more specialized than long; you can pass any bool argument as a long argument, but not vice versa.It feels like there should at least be ambiguity. ...This would be an enhancement. (A possible rule to add would be that literal-level conversions cannot influence the chosen overload.)
Apr 25 2013
On 2013-04-25, 23:05, Ali =C3=87ehreli wrote:This question has first appeared on D.learn: http://forum.dlang.org/post/vlosugoeuobjrdfaeegk forum.dlang.org A simple program: import std.stdio; void foo(bool b) { writeln("bool"); } void foo(long l) { writeln("long"); } void main() { foo(1); foo(2); } The program calls two separate foo() overloads for 1 and 2: bool long According to the language spec, both overloads match the int argument =by ="implicit conversion" as described under "Function Overloading" here: http://dlang.org/function.html Then, the overload must be resolved by partial ordering: "If two or mo=re =functions have the same match level, then partial ordering is used to ==try to find the best match. Partial ordering finds the most specialize=d =function." Is bool more specialized than long or is this a bug? Intuitively, both==should match the 'long' overload. It feels like there should at least =be =ambiguity.For what it's worth, this is ambiguous in C++. -- = Simen
Apr 25 2013
Is bool more specialized than longYes, because a bool can be implicitly converted to a long, but a long cannot be implicitly converted to a bool.
Apr 25 2013
On Friday, 26 April 2013 at 00:35:33 UTC, Walter Bright wrote:As we have bool literals as true and false, I don't think 1 should match bool in the first place.Is bool more specialized than longYes, because a bool can be implicitly converted to a long, but a long cannot be implicitly converted to a bool.
Apr 25 2013
On Thursday, April 25, 2013 17:35:34 Walter Bright wrote:However, given that bool isn't even an integral type, it seems very wrong that it would be a better match than something which _is_ an integral type. Given that the compiler already inserts explicit casts to bool in conditions to solve the primary case where you want a non-boolean value to implicitly convert to bool, it really seems to me that the other conversions to and from bool which are currently accepted are far too lax. Another example of this would be something like "foo" ~ true. I don't understand why conversions like that are allowed by the spec. They're just going to cause bugs. - Jonathan M DavisIs bool more specialized than longYes, because a bool can be implicitly converted to a long, but a long cannot be implicitly converted to a bool.
Apr 25 2013
On Friday, 26 April 2013 at 02:29:07 UTC, Jonathan M Davis wrote:On Thursday, April 25, 2013 17:35:34 Walter Bright wrote:And indeed they do. I did face some very weird bugs caused by that already.However, given that bool isn't even an integral type, it seems very wrong that it would be a better match than something which _is_ an integral type. Given that the compiler already inserts explicit casts to bool in conditions to solve the primary case where you want a non-boolean value to implicitly convert to bool, it really seems to me that the other conversions to and from bool which are currently accepted are far too lax. Another example of this would be something like "foo" ~ true. I don't understand why conversions like that are allowed by the spec. They're just going to cause bugs. - Jonathan M DavisIs bool more specialized than longYes, because a bool can be implicitly converted to a long, but a long cannot be implicitly converted to a bool.
Apr 25 2013
And indeed they do. I did face some very weird bugs caused by that already.What sort of bugs has it caused for you? Just interested, not questioning whether or not it's a source of bugs.
Apr 26 2013
On Friday, 26 April 2013 at 12:34:55 UTC, ixid 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. I don't have the actual code as I threw it away (because it was bogous) but took me several hours to figure it out.And indeed they do. I did face some very weird bugs caused by that already.What sort of bugs has it caused for you? Just interested, not questioning whether or not it's a source of bugs.
Apr 26 2013
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
Apr 26 2013
On Friday, 26 April 2013 at 18:22:10 UTC, Walter Bright wrote:On 4/26/2013 6:51 AM, deadalnix wrote:import std.stdio; void main() { bool c0 = '\1'; //compiled OK bool c1 = '\0'; //compiled OK writeln(c0,' ',c1); //output: true false }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
Apr 27 2013
Is is acceptable for 1 to match bool and 2 long? Maybe it is not acceptable in a serious language with strong typing... Bye, bearophile
Apr 25 2013
On Thursday, 25 April 2013 at 21:05:43 UTC, Ali Çehreli wrote:This question has first appeared on D.learn: ... The program calls two separate foo() overloads for 1 and 2: bool long According to the language spec, both overloads match the int argument by "implicit conversion" as described under "Function Overloading" here: http://dlang.org/function.html Then, the overload must be resolved by partial ordering: "If two or more functions have the same match level, then partial ordering is used to try to find the best match. Partial ordering finds the most specialized function." Is bool more specialized than long or is this a bug? Intuitively, both should match the 'long' overload. It feels like there should at least be ambiguity. AliLooks like value range propagation bug because 1 is integer literal and should be converted to long. There is no way for 1 to be converted to bool here (from TDPL long is below int and it is the shortest way, value range propagation can work upwards, but the path would be longer).
Apr 25 2013
On 04/25/2013 06:44 PM, Maxim Fomin wrote:On Thursday, 25 April 2013 at 21:05:43 UTC, Ali Çehreli wrote:Looks like value range propagation bug because 1 is integer literal and should be converted to long. There is no way for 1 to be converted to bool hereThat special conversion rule of literal 0 and literal 1 being implicitly convertible to false and true gets in the way.(from TDPL long is below int and it is the shortest way, value range propagation can work upwards, but the path would be longer).Interesting. I agree with bearophile, this is too surprising: foo(1); // goes to bool Decide to change the value: foo(2); // now goes to long Introduce a variable: int i = 1; foo(i); // again, goes to long I feel defeated. :) Ali
Apr 25 2013
On 4/26/13, Ali =C7ehreli <acehreli yahoo.com> wrote:Introduce a variable: int i =3D 1; foo(i); // again, goes to longAn even better example: enum e =3D 1; void main() { foo(e); // bool } static e =3D 1; void main() { foo(e); // long } I find this unacceptable.
Apr 25 2013
On Friday, 26 April 2013 at 02:13:03 UTC, Ali Çehreli wrote:On 04/25/2013 06:44 PM, Maxim Fomin wrote:Sorry but I am not aware of how 1 is converted to bool here. True, that 1 is convertible to true, but here there is function with long parameter.On Thursday, 25 April 2013 at 21:05:43 UTC, Ali Çehreli wrote:Looks like value range propagation bug because 1 is integerliteral andshould be converted to long. There is no way for 1 to beconverted tobool hereThat special conversion rule of literal 0 and literal 1 being implicitly convertible to false and true gets in the way.(from TDPL long is below int and it is the shortest way, value range propagation can work upwards, but the path would belonger). Ali
Apr 26 2013
On 04/26/2013 12:03 AM, Maxim Fomin wrote:On Friday, 26 April 2013 at 02:13:03 UTC, Ali Çehreli wrote:Yes, through an implicit conversion.On 04/25/2013 06:44 PM, Maxim Fomin wrote:Sorry but I am not aware of how 1 is converted to bool here. True, that 1 is convertible to true,On Thursday, 25 April 2013 at 21:05:43 UTC, Ali Çehreli wrote:Looks like value range propagation bug because 1 is integerliteral andshould be converted to long. There is no way for 1 to beconverted tobool hereThat special conversion rule of literal 0 and literal 1 being implicitly convertible to false and true gets in the way.(from TDPL long is below int and it is the shortest way, value range propagation can work upwards, but the path would belonger). Alibut here there is function with long parameter.Since the type of literal 1 is int, calling foo(long) would require an implicit conversion as well: from int to long. In the end, both functions are candidates because they both accept 1 by one implicit conversion. Ali
Apr 26 2013
On 4/26/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:An even better example:import std.stdio; void foo(bool x) { writeln("1"); } void foo(long x) { writeln("2"); } void main() { foo(1); // "1" foo(false ? 2 : 1); // "2" } Kill it with fire.
Apr 26 2013
On 4/26/2013 1:59 PM, Andrej Mitrovic wrote:On 4/26/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:How about this one: import std.stdio; void foo(short x) { writeln("1"); } void foo(long x) { writeln("2"); } void main() { foo(30000); // "1" foo(false ? 40000 : 30000); // "2" }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.
Apr 26 2013
On Friday, 26 April 2013 at 21:37:14 UTC, Walter Bright wrote:On 4/26/2013 1:59 PM, Andrej Mitrovic wrote:We all know that short and long are integer numerics, however most of us do not think of bool as being a 1 bit integer type. We expect values of 'true' and 'false' because D has explicit 'true' and 'false' values, which presumably are there because 1 and 0 which are not the same thing as 'true' and 'false', otherwise there would be no need for 'true' and 'false'. --rtOn 4/26/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:How about this one: import std.stdio; void foo(short x) { writeln("1"); } void foo(long x) { writeln("2"); } void main() { foo(30000); // "1" foo(false ? 40000 : 30000); // "2" }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.
Apr 26 2013
On Friday, 26 April 2013 at 21:37:14 UTC, Walter Bright wrote:On 4/26/2013 1:59 PM, Andrej Mitrovic wrote:Walter, you're completely missing the point. The point is that people can live with the consequences of your short/long example, but they can't do the same with Andrej's bool/long example. No matter how right you are, if you keep insisting your way is correct, D will continue never becoming popular because people will continue finding it hard to use. I think at some point it's worth noticing that "ease of use" is _not_ a linear function of "technical correctness". You may be right in technicality but that doesn't mean you're right on the UI side.On 4/26/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:How about this one: import std.stdio; void foo(short x) { writeln("1"); } void foo(long x) { writeln("2"); } void main() { foo(30000); // "1" foo(false ? 40000 : 30000); // "2" }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.
Apr 26 2013
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.
Apr 27 2013
On Saturday, 27 April 2013 at 19:51:48 UTC, Walter Bright wrote:On 4/26/2013 7:36 PM, Mehrdad wrote: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?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.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
Apr 27 2013
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'sBecause 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
Apr 27 2013
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.
Apr 27 2013
On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:On 4/27/2013 2:29 PM, Rob T wrote:I would expect boolean literals to be something like 0b and 1b, not true and false then.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.
Apr 27 2013
On 4/27/2013 2:58 PM, jerro wrote:On Saturday, 27 April 2013 at 21:52:30 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.On 4/27/2013 2:29 PM, Rob T wrote:I would expect boolean literals to be something like 0b and 1b, not true and false then.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.
Apr 28 2013
On Sunday, 28 April 2013 at 19:19:53 UTC, Walter Bright wrote:On 4/27/2013 2:58 PM, jerro wrote: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 indexOn Saturday, 27 April 2013 at 21:52:30 UTC, Walter BrightTo 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.
Apr 28 2013
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:This is plain useless as a cast is already inserted here.On 4/27/2013 2:58 PM, jerro wrote: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()).On Saturday, 27 April 2013 at 21:52:30 UTC, Walter BrightTo 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.
Apr 29 2013
On Monday, 29 April 2013 at 12:30:06 UTC, deadalnix wrote:On Sunday, 28 April 2013 at 19:38:26 UTC, eles wrote:so, only allow explict casting then.On Sunday, 28 April 2013 at 19:19:53 UTC, Walter Bright wrote:This is plain useless as a cast is already inserted here.On 4/27/2013 2:58 PM, jerro wrote:On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright
Apr 29 2013
On 4/29/2013 7:30 AM, deadalnix wrote: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'(that is: ifzero(), infnonzero(), whilezero(), whilenonzero()).
Apr 29 2013
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.
Apr 29 2013
On Sunday, 28 April 2013 at 19:19:53 UTC, Walter Bright wrote:On 4/27/2013 2:58 PM, jerro wrote: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::vector<bool>On Saturday, 27 April 2013 at 21:52:30 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.On 4/27/2013 2:29 PM, Rob T wrote:I would expect boolean literals to be something like 0b and 1b, not true and false then.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.
Apr 28 2013
On 04/28/2013 10:54 PM, Mehrdad wrote:On Sunday, 28 April 2013 at 19:19:53 UTC, Walter Bright wrote:"History".... 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::vector<bool>The issues surrounding vector<bool> are entirely unrelated.
Apr 28 2013
On Sunday, 28 April 2013 at 21:29:06 UTC, Timon Gehr wrote:On 04/28/2013 10:54 PM, Mehrdad wrote:Huh? It's entirely related. The fact that sizeof(bool) * 8 != sizeof(byte) is what causes problems in vector<bool> (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.- std::vector<bool>The issues surrounding vector<bool> are entirely unrelated.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?
Apr 28 2013
On 04/28/2013 11:51 PM, Mehrdad wrote:On Sunday, 28 April 2013 at 21:29:06 UTC, Timon Gehr wrote:Exactly. This is not the problem here.On 04/28/2013 10:54 PM, Mehrdad wrote:Huh? It's entirely related. The fact that sizeof(bool) * 8 != sizeof(byte) is what causes problems in vector<bool>- std::vector<bool>The issues surrounding vector<bool> are entirely unrelated.(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.Please make sure your statements make sense.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?
Apr 28 2013
On Sunday, 28 April 2013 at 22:25:43 UTC, Timon Gehr wrote:On 04/28/2013 11:51 PM, Mehrdad wrote: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?On Sunday, 28 April 2013 at 21:29:06 UTC, Timon Gehr wrote:Please make sure your statements make sense.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?
Apr 28 2013
On 04/29/2013 12:51 AM, Mehrdad wrote:On Sunday, 28 April 2013 at 22:25:43 UTC, Timon Gehr wrote: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.)On 04/28/2013 11:51 PM, Mehrdad wrote:Huh? Walter says bool is an integer,On Sunday, 28 April 2013 at 21:29:06 UTC, Timon Gehr wrote:Please make sure your statements make sense.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?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".
Apr 28 2013
On Sunday, 28 April 2013 at 23:11:50 UTC, Timon Gehr wrote:On 04/29/2013 12:51 AM, Mehrdad wrote:Sheesh, s/bool/a bool/.On Sunday, 28 April 2013 at 22:25:43 UTC, Timon Gehr wrote:Certainly not. bool is a type. 2 is an integer.On 04/28/2013 11:51 PM, Mehrdad wrote:Huh? Walter says bool is an integer,On Sunday, 28 April 2013 at 21:29:06 UTC, Timon Gehr wrote:Please make sure your statements make sense.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?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
Apr 28 2013
On 4/28/13 7:19 PM, Mehrdad wrote:Integer logic: 1 + 1 = 2 = 0 (mod 2) Boolean logic: 1 + 1 = 1 = 1Well 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
Apr 28 2013
On Sunday, 28 April 2013 at 23:37:23 UTC, Andrei Alexandrescu wrote:On 4/28/13 7:19 PM, Mehrdad wrote: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)Integer logic: 1 + 1 = 2 = 0 (mod 2) Boolean logic: 1 + 1 = 1 = 1Well 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 *.
Apr 28 2013
On Sunday, 28 April 2013 at 23:47:20 UTC, Mehrdad wrote:2. Stop allowing implicit bool->int conversionsAnd implicit int->bool as well, forgot to mention that.
Apr 28 2013
On 4/28/13 7:47 PM, Mehrdad wrote:In other words, we need to either: 1. Make int->bool truncate, orNot 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
Apr 28 2013
On Monday, 29 April 2013 at 00:40:08 UTC, Andrei Alexandrescu wrote:What's the use case against it?2. Stop allowing implicit bool->int conversions (explicit conversions like in if/while/etc. are of course not included here)Unlikely to ever happen.
Apr 28 2013
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:This is useful, and do not cause problem by itself. The reverse conversion is problematic.What's the use case against it?2. Stop allowing implicit bool->int conversions (explicit conversions like in if/while/etc. are of course not included here)Unlikely to ever happen.
Apr 29 2013
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 (k&r).
Apr 27 2013
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: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). --rtOn 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.
Apr 27 2013
On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:On 4/27/2013 2:29 PM, Rob T wrote:Unappealing to whom?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.
Apr 27 2013
Am 27.04.2013 23:52, schrieb Walter Bright:On 4/27/2013 2:29 PM, Rob T wrote:No, this brings us back into the realm of C and weak type checking.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.
Apr 27 2013
On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:On 4/27/2013 2:29 PM, Rob T wrote: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). --rtIf 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.
Apr 27 2013
On Saturday, April 27, 2013 14:52:31 Walter Bright wrote:On 4/27/2013 2:29 PM, Rob T wrote: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 DavisIf 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.
Apr 27 2013
On 04/28/2013 02:28 AM, Jonathan M Davis wrote:... I like being able to do while(1) because it's shorter, ...for(;;) is shorter.
Apr 27 2013
On Sunday, April 28, 2013 02:53:04 Timon Gehr wrote:On 04/28/2013 02:28 AM, Jonathan M Davis wrote:True, but I'd never use it, because I'd never use a for loop for anything that didn't involve either creating a variable in the first portion of the for or doing something in the last portion. I also find it very bizarre that it's legal to have a loop _without_ a condition like for(;;) does. If you couldn't do while(1), I'd do while(true) and never for(;;), but that's obviously a matter of preference, and while I like being able to do while(1), I'd gladly give it up if that meant that we stopped treating bool as in integral type. - Jonathan M Davis... I like being able to do while(1) because it's shorter, ...for(;;) is shorter.
Apr 27 2013
On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:On 4/27/2013 2:29 PM, Rob T wrote:VRP say you don't need to.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.
Apr 28 2013
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: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 . . .On 4/27/2013 2:29 PM, Rob T wrote:VRP say you don't need to.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.
Apr 28 2013
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: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? --rtOn 4/27/2013 2:29 PM, Rob T wrote:VRP say you don't need to.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.
Apr 28 2013
On 04/28/2013 11:05 AM, deadalnix wrote:On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:void foo(bool b){ } // 1 void foo(int i){ } // 2 void main(){ foo(cast(bool)0); // calls 1 foo(0); // calls 2 }On 4/27/2013 2:29 PM, Rob T wrote:VRP say you don't need to.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.
Apr 28 2013
On 4/28/2013 2:05 AM, deadalnix wrote:On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote: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.On 4/27/2013 2:29 PM, Rob T wrote:VRP say you don't need to.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.
Apr 28 2013
On Monday, 29 April 2013 at 06:26:44 UTC, Walter Bright wrote:On 4/28/2013 2:05 AM, deadalnix wrote: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.On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote: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.On 4/27/2013 2:29 PM, Rob T wrote:VRP say you don't need to.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.
Apr 29 2013
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: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++;On 4/28/2013 2:05 AM, deadalnix 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.On Saturday, 27 April 2013 at 21:52:30 UTC, Walter Bright wrote:On 4/27/2013 2:29 PM, Rob T wrote:
Apr 29 2013
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++;
Apr 29 2013
On Monday, 29 April 2013 at 14:08:20 UTC, Mike James wrote: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.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.
Apr 29 2013
On Monday, 29 April 2013 at 14:08:20 UTC, Mike James wrote: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. --rtgdc: 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++;
Apr 29 2013
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.
Apr 27 2013
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
Apr 27 2013
On Saturday, 27 April 2013 at 19:51:48 UTC, Walter Bright wrote:On 4/26/2013 7:36 PM, Mehrdad wrote:Don't be silly. You don't see them as 1 bit integer, as they convert by comparing to 0 and not truncating.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).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.It is not like this issue is popping for the first time. When a source of tension exists, any complaint about it can crystallize easily.
Apr 27 2013
On Sunday, 28 April 2013 at 01:54:50 UTC, deadalnix wrote:Don't be silly. You don't see them as 1 bit integer, as they convert by comparing to 0 and not truncating.This corroborates Rob T's positions that the current bool type tries to be both a bit and a logical Boolean and ends up not quite living to either, right? Also, while reading this thread I kept wondering: if some tweak of bool was decided, wouldn't it be great to have something like Go's gofmt for automatic conversion of existing code?
Apr 27 2013
On Sat, 27 Apr 2013 12:51:48 -0700, Walter Bright <newshound2 digitalmars.com> wrote:On 4/26/2013 7:36 PM, Mehrdad wrote:short x = cast(short)0x10000; 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. -SteveWalter, 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).
Apr 29 2013
On Monday, April 29, 2013 09:54:40 Steven Schveighoffer wrote:On Sat, 27 Apr 2013 12:51:48 -0700, Walter Bright <newshound2 digitalmars.com> wrote: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 DavisOn 4/26/2013 7:36 PM, Mehrdad wrote:short x = cast(short)0x10000; 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.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).
Apr 29 2013
On Friday, 26 April 2013 at 21:37:14 UTC, Walter Bright wrote:On 4/26/2013 1:59 PM, Andrej Mitrovic wrote:VRP should be used as a fallback mechanism. Yes, kill it with fire.On 4/26/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:How about this one: import std.stdio; void foo(short x) { writeln("1"); } void foo(long x) { writeln("2"); } void main() { foo(30000); // "1" foo(false ? 40000 : 30000); // "2" }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.
Apr 27 2013
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: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.On 4/26/2013 1:59 PM, Andrej Mitrovic wrote:VRP should be used as a fallback mechanism. Yes, kill it with fire.On 4/26/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:How about this one: import std.stdio; void foo(short x) { writeln("1"); } void foo(long x) { writeln("2"); } void main() { foo(30000); // "1" foo(false ? 40000 : 30000); // "2" }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.
Apr 27 2013
First, I can guess that why Walter disagree *fixing* this problem. http://dlang.org/overview.htmlMajor Design Goals of D 9. Where D code looks the same as C code, have it either behave the sameor 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 <newshound2 digitalmars.com>On 4/26/2013 1:59 PM, Andrej Mitrovic wrote:On 4/26/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:How about this one: import std.stdio; void foo(short x) { writeln("1"); } void foo(long x) { writeln("2"); } void main() { foo(30000); // "1" foo(false ? 40000 : 30000); // "2" }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.
Apr 27 2013
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.htmlC doesn't have a bool type, so how can D behave the same?Major Design Goals of D 9. Where D code looks the same as C code, have it either behave the sameor issue an error.
Apr 27 2013
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_mina1990 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.htmlC doesn't have a bool type, so how can D behave the same?Major Design Goals of D 9. Where D code looks the same as C code, have it either behave the sameor issue an error.
Apr 27 2013
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.
Apr 27 2013
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.)
Apr 27 2013
2013/4/28 Walter Bright <newshound2 digitalmars.com>On 4/27/2013 8:11 AM, kenji hara wrote: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 HaraWalter, 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.)
Apr 27 2013
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.
Apr 27 2013
On 4/27/2013 3:58 PM, Walter Bright wrote:On 4/27/2013 1:26 PM, kenji hara wrote:Note that the following is also ambiguous in C++: void foo(bool b) { } void foo(long l) { } void main() { foo(3); }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.
Apr 27 2013
2013/4/28 Walter Bright <newshound2 digitalmars.com>On 4/27/2013 3:58 PM, Walter Bright wrote:Yes, but all C++ users would accept the behavior - In C++, all integer types are treated as bool type under the rule that zero/non-zero value is equivalent to false /true. From the view of D user, it looks inconvenient, but there is still few and consistent rule. 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. ---- Now I doubt that this problem comes from the history of D and wrong dmd implementation. In early D1 age, we had had 'bit' type which exactly have one bit value 0 and 1. After the while, the name 'bit' changed to 'bool'. At that point, 'bool' was kept the characteristics that it is one of the integer types - even though we should discard it. Right? VRP is a new concept that introduced in D2 age. But, maybe, the combination of bool and VRP had not been considered enough. So now problem is appeared there. Now it feels to me that is a debt from D1. Kenji HaraOn 4/27/2013 1:26 PM, kenji hara wrote:Note that the following is also ambiguous in C++: void foo(bool b) { } void foo(long l) { } void main() { foo(3); }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.
Apr 27 2013
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.
Apr 28 2013
On Sunday, 28 April 2013 at 08:40:01 UTC, Walter Bright wrote:On 4/27/2013 9:38 PM, kenji hara wrote:Then be consistent. Convert int to bool by truncating.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.
Apr 28 2013
On 4/28/13 4:40 AM, Walter Bright wrote:On 4/27/2013 9:38 PM, kenji hara wrote: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: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.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
Apr 28 2013
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).
Apr 28 2013
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.
Apr 28 2013
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
Apr 29 2013
A real issue against disallowing 0/1 to bool conversion is in the translation code from C/C++ to D. For example, old C code may have thus macro constant. #define FALSE 0 #define TRUE 1 #define BOOL int void foo(BOOL flag); foo(FALSE); Translating the code to D: enum FALSE = 0; enum TRUE = 1; alias BOOL = int; void foo(BOOL flag); foo(FALSE); And then, we can misuse FALSE and TRUE. void bar(bool flag); bar(FALSE); // int argument FALSE(==0) now matches to bool This is enough realistic case. We already have an actual case in core.sys.windows.windows: enum : int { FALSE = 0, TRUE = 1, } And core sys windows.stacktrace: if (!dbghelp.SymInitialize(hProcess, generateSearchPath().ptr, TRUE)) return; (dbghelp.SymInitialize is a function pointer that defined as alias BOOL function(HANDLE hProcess, PCSTR UserSearchPath, bool fInvadeProcess) SymInitializeFunc; struct DbgHelp { SymInitializeFunc SymInitialize; ... } ) If we change the behavior, we should accept the existing code break. Kenji Hara
Apr 27 2013
(This is a quotation from http://d.puremagic.com/issues/show_bug.cgi?id=9999<http://d.puremagic.com/issues/show_bug.cgi?id=9999#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 implicitlyconvertibleto '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.pg gmail.com>2013/4/28 Walter Bright <newshound2 digitalmars.com>On 4/27/2013 8:11 AM, kenji hara wrote: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 HaraWalter, 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.)
Apr 27 2013
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 ) ?
Apr 27 2013
I filed the issue in bugzilla, and opened pull request to fix it. http://d.puremagic.com/issues/show_bug.cgi?id=9999 https://github.com/D-Programming-Language/dmd/pull/1942 Kenji Hara 2013/4/28 kenji hara <k.hara.pg 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_mina1990 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.htmlC doesn't have a bool type, so how can D behave the same?Major Design Goals of D 9. Where D code looks the same as C code, have it either behave the sameor issue an error.
Apr 27 2013
On 4/27/13, kenji hara <k.hara.pg 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.
Apr 27 2013
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
Apr 27 2013
On Saturday, 27 April 2013 at 12:20:00 UTC, bearophile wrote:Andrej Mitrovic:No, that is even worse.That's even more stupid.Please be gentle. That from Kenji is one of the few usable ideas of this thread. Bye, bearophile
Apr 27 2013
This is just silly. Changing enum defaultVal = 1 to defaultVal = 2 should never result in calling a different overload.
Apr 25 2013
On 4/25/2013 7:54 PM, Kapps wrote:This is just silly. Changing enum defaultVal = 1 to defaultVal = 2 should never result in calling a different overload.This does: ------------------------ import core.stdc.stdio; enum x = 10000; enum y = 40000; int foo(short s) { return 1; } int foo(long s) { return 2; } void main() { printf("%d\n", foo(x)); printf("%d\n", foo(y)); } ------------------------- A bool is an integer with the range 0..1
Apr 25 2013
On 04/25/2013 10:02 PM, Walter Bright wrote:> On 4/25/2013 7:54 PM, Kapps wrote:It certainly behaves that way but it isn't an integer type and that's why it is unintuitive. bool is a type with two values: false and true with the following conversion rules: false -> 0 true -> 1 0 value -> false non-zero value -> true 0 literal -> false The following are the problematic ones: 1 literal -> true non-zero and non-one *literal* -> Not a bool! That last rule is the problem. Since we cannot get rid of the last rule, to be consistent, we should make literal 1 match an integer type better than bool. AliThis is just silly. Changing enum defaultVal = 1 to defaultVal = 2 should never result in calling a different overload.This does: ------------------------ import core.stdc.stdio; enum x = 10000; enum y = 40000; int foo(short s) { return 1; } int foo(long s) { return 2; } void main() { printf("%d\n", foo(x)); printf("%d\n", foo(y)); } ------------------------- A bool is an integer with the range 0..1
Apr 25 2013
On 4/25/2013 10:49 PM, Ali Çehreli wrote:It certainly behaves that way but it isn't an integer type and that's why it is unintuitive.But it is an integer type.bool is a type with two values: false and true with the following conversion rules: false -> 0 true -> 1 0 value -> false non-zero value -> true 0 literal -> false The following are the problematic ones: 1 literal -> true non-zero and non-one *literal* -> Not a bool! That last rule is the problem. Since we cannot get rid of the last rule, to be consistent, we should make literal 1 match an integer type better than bool.Whether it's a problem or not depends on one's perspective. The next issue is the notion of a "better" match. This notion is very complex in C++, and still produces odd results. Very few people can explain how it works - it's kind of shoot and hope you hit the target. D tries very hard to avoid the notion of a "better" match. It goes with an exact match, followed by one with implicit conversions. All implicit conversions are considered equally good. Ambiguity is resolved by invoking "partial ordering", which was explained elsewhere in this thread. Partial ordering does not at all consider "better" matches. Once you venture down the path of "better" matches, it's all roses at first, but look at where C++ wound up with it. It didn't intend to arrive there, it inevitably arrived there. The real issue is do you want to have the implicit conversions: 0 => false 1 => true or would you require a cast?
Apr 25 2013
On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:The real issue is do you want to have the implicit conversions: 0 => false 1 => true or would you require a cast?Yes.
Apr 25 2013
On Friday, 26 April 2013 at 06:18:29 UTC, deadalnix wrote:On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:+1 What about the implicit conversion for the other types? I could imagine that they could cause similar bugs. Why not get rid of the implicit conversion? How about yet another compiler flag?The real issue is do you want to have the implicit conversions: 0 => false 1 => true or would you require a cast?Yes.
Apr 25 2013
On 4/25/2013 11:42 PM, Manipulator wrote:What about the implicit conversion for the other types? I could imagine that they could cause similar bugs. Why not get rid of the implicit conversion?Implicit conversions make the menagerie of integer types tractable. Explicit casts are a sledgehammer that often causes bugs rather than eliminates them.How about yet another compiler flag?Compiler flags that alter the meaning of the language are not the solution.
Apr 26 2013
On Friday, 26 April 2013 at 06:42:28 UTC, Manipulator wrote:On Friday, 26 April 2013 at 06:18:29 UTC, deadalnix wrote:No no no no, please no.On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:+1 What about the implicit conversion for the other types? I could imagine that they could cause similar bugs. Why not get rid of the implicit conversion? How about yet another compiler flag?The real issue is do you want to have the implicit conversions: 0 => false 1 => true or would you require a cast?Yes.
Apr 26 2013
On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:On 4/25/2013 10:49 PM, Ali Çehreli wrote:Regarding bool type as integer type is C atavism and should be abandoned. This leads to comic sitatuation presented in the thread when changing literal to lvalue or using different enums changes overloading matching.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.
Apr 26 2013
On 4/26/2013 12:07 AM, Maxim Fomin wrote:Regarding bool type as integer type is C atavism and should be abandoned.There's a very loooong history of 0 being regarded as false and 1 as true - it goes well beyond C.This leads to comic sitatuation presented in the thread when changing literal to lvalue or using different enums changes overloading matching.Yet I showed an analogous example where different overloads were selected based on a different integer value. There's no getting away from having to pay attention when declaring different overloads of a function. In the original example, the correct solution is to provide a foo(int). I'd be suspicious of any code that only had overloads on just bool and long - it doesn't make sense.
Apr 26 2013
On Friday, 26 April 2013 at 08:00:28 UTC, Walter Bright wrote:On 4/26/2013 12:07 AM, Maxim Fomin wrote:This should be irrelevant in case of long parameter. Such conversion should not be in the language (like feature of array to pointer conversion and function to pointer to function conversion is present in C but not in D).Regarding bool type as integer type is C atavism and should be abandoned.There's a very loooong history of 0 being regarded as false and 1 as true - it goes well beyond C.I argue the correct solution is to call integer function with integer parameter when integer value is passed. Adjusting to buggy compiler behavior isn't a good idea.This leads to comic sitatuation presented in the thread when changing literal to lvalue or using different enums changes overloading matching.Yet I showed an analogous example where different overloads were selected based on a different integer value. There's no getting away from having to pay attention when declaring different overloads of a function. In the original example, the correct solution is to provide a foo(int). I'd be suspicious of any code that only had overloads on just bool and long - it doesn't make sense.
Apr 26 2013
On 4/26/2013 1:14 AM, Maxim Fomin wrote:I argue the correct solution is to call integer function with integer parameter when integer value is passed.I'm sorry, but that's an assertion not an argument. The other issue with your assertion, as I explained to Ali, is that D does not have a notion of "better" implicit conversions, and it would be a tragedy to add them.Adjusting to buggy compiler behavior isn't a good idea.It's working as designed - it is not a compiler bug.
Apr 26 2013
On Friday, 26 April 2013 at 08:00:28 UTC, Walter Bright wrote:On 4/26/2013 12:07 AM, Maxim Fomin wrote:Assembly, PL/I, Algol, ...? Just asking as a language geek. Personally, given my strong typing background, I dislike the automatic conversion to booleans. Even my C code has explicit comparisons for NULL pointers, instead of relying in implicit conversions. -- PauloRegarding bool type as integer type is C atavism and should be abandoned.There's a very loooong history of 0 being regarded as false and 1 as true - it goes well beyond C.
Apr 26 2013
On Friday, 26 April 2013 at 08:00:28 UTC, Walter Bright wrote:On 4/26/2013 12:07 AM, Maxim Fomin wrote:That is true, but even in theses elder languages, bool is handled as a special case, and not as an regular integral type. For instance, when integral conversion to smaller type is done by applying a mask (or doing a modulo, this is the same thing in this case) it is done by comparing to 0 to compare to bool.Regarding bool type as integer type is C atavism and should be abandoned.There's a very loooong history of 0 being regarded as false and 1 as true - it goes well beyond C.
Apr 26 2013
On 4/26/2013 7:33 AM, deadalnix wrote:On Friday, 26 April 2013 at 08:00:28 UTC, Walter Bright wrote:I've also spent time with embedded systems that manipulated things by writing out 0's and 1's to ports, designed ABEL (a language for programming PLDs), and simply worked a lot with digital math. 0 and 1 being synonymous with false and true is deeply embedded. A bool is a one bit integer. I remember once a language that tried to define true and false as something other than 1 and 0. It was horrible.On 4/26/2013 12:07 AM, Maxim Fomin wrote:That is true, but even in theses elder languages, bool is handled as a special case, and not as an regular integral type. For instance, when integral conversion to smaller type is done by applying a mask (or doing a modulo, this is the same thing in this case) it is done by comparing to 0 to compare to bool.Regarding bool type as integer type is C atavism and should be abandoned.There's a very loooong history of 0 being regarded as false and 1 as true - it goes well beyond C.
Apr 26 2013
On Friday, 26 April 2013 at 19:22:51 UTC, Walter Bright wrote:I remember once a language that tried to define true and false as something other than 1 and 0. It was horrible.Don't need to look far away. Most shell do that.
Apr 26 2013
On Saturday, 27 April 2013 at 01:37:22 UTC, deadalnix wrote:On Friday, 26 April 2013 at 19:22:51 UTC, Walter Bright wrote:D can still cast true to 1 and false to 0. It is solely the implicit casting that is inappropriate under rather common circumstances. --rtI remember once a language that tried to define true and false as something other than 1 and 0. It was horrible.Don't need to look far away. Most shell do that.
Apr 26 2013
Is this what some of you are asking for? bool a = true; // ok bool b = false; // ok bool c = 1; // error, no implicit conversion bool c = getInt(); // error? ok? int x = 42; if(x) { ... } // ok (doesn't this imply c = getInt() ok too? if(42) { ... } // ok
Apr 26 2013
On Saturday, 27 April 2013 at 05:54:48 UTC, Luís Marques wrote:Is this what some of you are asking for? bool a = true; // okYesbool b = false; // okYesbool c = 1; // error, no implicit conversionYesbool c = getInt(); // error? ok?Yes (error)int x = 42; if(x) { ... } // ok (doesn't this imply c =YesgetInt() ok too?Yesif(42) { ... } // okYes
Apr 26 2013
On Saturday, 27 April 2013 at 05:54:48 UTC, Luís Marques wrote:Is this what some of you are asking for? bool a = true; // ok 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) { ... } // okif insert a cast already, so all are ok.
Apr 27 2013
On Saturday, April 27, 2013 07:54:44 =?UTF-8?B?Ikx1w61z?=.Marques <luismarques gmail.com> puremagic.com 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? int x = 42; if(x) { ... } // ok (doesn't this imply c = getInt() ok too? if(42) { ... } // okif conditions and loop conditions automatically insert explicit casts, so if(foo) becomes if(cast(bool)foo) 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). - Jonathan M Davis
Apr 27 2013
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!
Apr 28 2013
On 04/28/2013 09:16 PM, Walter Bright wrote:On 4/27/2013 5:53 PM, Jonathan M Davis wrote:He is saying that VRP is irrelevant in a boolean evaluation context.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!
Apr 28 2013
On Sunday, April 28, 2013 12:16:58 Walter Bright wrote:On 4/27/2013 5:53 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. - Jonathan M Daviswhich 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!
Apr 28 2013
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!
Apr 28 2013
On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:On 4/25/2013 10:49 PM, Ali Çehreli wrote:It is an integral type _internally_. A bool type should have the values true/false. When someone sees foo(45) he expects it to call an overload that receives an _integral_ value. Which overload is going to be called is a detail (short or long in this example). It is confusing to call an overload that takes bool. Boolean are true/false, not 0, 1 or anything else.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.
Apr 26 2013
On Thursday, April 25, 2013 23:01:30 Walter Bright wrote:On 4/25/2013 10:49 PM, Ali Çehreli wrote:That was one of C's big mistakes. There's nothing whatsoever about bool that makes sense as an integral type. true and false have nothing to do with 1 and 0 or any other integeral values. Having non-boolean values such as 1 and 0 implicitly convert to bool under some set of circumstances can be very useful (which is why cast(bool) is implicitly used in conditions), but in the general case, it just causes bugs.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.The real issue is do you want to have the implicit conversions: 0 => false 1 => true or would you require a cast?Emphatically yes. The main place where casting would be annoying - if conditions and loop conditions - already insert an explicit cast underneat the hood. Other cases should require explicit casts; otherwise, we're just going to have bugs as has already been pointed out in this thread and has come up a number of times previously in the newsroup (one of the favorites being "foo" ~ true). - Jonathan M Davis
Apr 26 2013
On Friday, 26 April 2013 at 19:37:48 UTC, Jonathan M Davis wrote:The main place where casting would be annoying - if conditions and loop conditions - already insert an explicit cast underneat the hood.IMO it still makes no sense to have the implicit casting done in conditional statements because it is not obvious why a given conditional should treat a zero differently than all other values. However at this stage retaining that old convention is perhaps unavoidable. At the very least, D should be minimizing the potential for programmers falling into the traps caused by non-intuitive implicit casting. In the case of bool, there's no obvious relationship with the int data type, so let's get rid of that arbitrary association, make casting explicit, and move on. --rt
Apr 26 2013
On 4/26/2013 12:37 PM, Jonathan M Davis wrote:There's nothing whatsoever about bool that makes sense as an integral type.This is where our perspectives sharply diverge. A bool is a 1 bit integer type. Take a look at this, for example: http://d.puremagic.com/issues/show_bug.cgi?id=9963 Mathematically, they behave like 1 bit integers and are useful that way.
Apr 26 2013
On Friday, 26 April 2013 at 21:14:54 UTC, Walter Bright wrote:A bool is a 1 bit integer type..sizeof returns bytes, not bits, and says that bool is of size 1.
Apr 26 2013
On Friday, 26 April 2013 at 21:14:54 UTC, Walter Bright wrote:On 4/26/2013 12:37 PM, Jonathan M Davis wrote:Uh, uh, that's not a bool. It is a bit (binary digit, just to be sure). That is: a figure of the base 2. The very definition of bit. I still have to see some computer course introducing a byte/octet as a group of 8... booleans. No: boolean is a logical entity and is true or false, while the bit is a figure (a number) and is 0 or 1. They may overlay for programming purposes to some extent (a bijection, after all), but let's not take the one for another. Why the computer theory invented the notion of bit? The term of "boolean" was available for centuries.There's nothing whatsoever about bool that makes sense as an integral type.This is where our perspectives sharply diverge. A bool is a 1 bit integer type. Take a look at this, for example:
Apr 26 2013
On Friday, April 26, 2013 14:14:55 Walter Bright wrote:On 4/26/2013 12:37 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. 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. However, we are clearly coming from very different points of view here. - Jonathan M DavisThere's nothing whatsoever about bool that makes sense as an integral type.This is where our perspectives sharply diverge. A bool is a 1 bit integer type. Take a look at this, for example: http://d.puremagic.com/issues/show_bug.cgi?id=9963 Mathematically, they behave like 1 bit integers and are useful that way.
Apr 26 2013
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.
Apr 27 2013
On Saturday, April 27, 2013 13:16:55 Walter Bright wrote: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.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. 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, 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.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.]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.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? 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. - Jonathan M DavisHowever, 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.
Apr 27 2013
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.
Apr 28 2013
On Friday, 26 April 2013 at 21:14:54 UTC, Walter Bright wrote:On 4/26/2013 12:37 PM, Jonathan M Davis wrote:Then why does it convert from int by comparing with 0 ? That isn't the behavior of an integral.There's nothing whatsoever about bool that makes sense as an integral type.This is where our perspectives sharply diverge. A bool is a 1 bit integer type.
Apr 26 2013
On Saturday, 27 April 2013 at 01:43:12 UTC, deadalnix wrote:On Friday, 26 April 2013 at 21:14:54 UTC, Walter Bright wrote:+1On 4/26/2013 12:37 PM, Jonathan M Davis wrote:Then why does it convert from int by comparing with 0 ? That isn't the behavior of an integral.There's nothing whatsoever about bool that makes sense as an integral type.This is where our perspectives sharply diverge. A bool is a 1 bit integer type.
Apr 26 2013
On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:The real issue is do you want to have the implicit conversions: 0 => false 1 => true or would you require a cast?The idea of a "true number" and a "false number" doesn't make sense, so yes.
Apr 26 2013
On Friday, 26 April 2013 at 21:01:17 UTC, Brian Schott wrote:On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:I find the current implementation perfectly intuitive and I wouldn´t want it any other way... it models the underlying hardware, just the way it should be. Sometimes due to bad coding standards I´m forced to write... if((.....long expression with not immediately apparent operator precedence)!=0) ... absolutely appalling, kills readability with extra () etc. doesn´t matter how many years, I was forced to do it, I still cringe every time I see a line like that and itch to rewrite it more readable. I also dont know any book(including Knuth), nor online article, which doesn´t clearly define it as 0,1... am very confused by the reactions in this thread, is my background so different from everyone elses?The real issue is do you want to have the implicit conversions: 0 => false 1 => true or would you require a cast?The idea of a "true number" and a "false number" doesn't make sense, so yes.
Apr 26 2013
On Friday, 26 April 2013 at 21:32:32 UTC, Tove wrote:On Friday, 26 April 2013 at 21:01:17 UTC, Brian Schott wrote:I assume you are doing C or C++. Under the preprocessor, why do not #define a ifnonzero() and a ifzero() macro, if that bothers you so much? (also works for testing against NULL). In D, it is less possible to do so (curse of lacking processor...). Or maybe it is and I am missing it.On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:Sometimes due to bad coding standards I´m forced to write... if((.....long expression with not immediately apparent operator precedence)!=0)
Apr 26 2013
Tove:Sometimes due to bad coding standards I´m forced to write... if((.....long expression with not immediately apparent operator precedence)!=0) ... absolutely appalling, kills readability with extra () etc.I think here people are not asking to disallow that. A 0 and 1 can be false and true in a boolean evaluation context even if they don't implicitly cast to int in other situations. Bye, bearophile
Apr 26 2013
On Friday, 26 April 2013 at 21:32:32 UTC, Tove wrote:On Friday, 26 April 2013 at 21:01:17 UTC, Brian Schott wrote:That is totally irrelevant as a cast is already inserted automatically.On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:I find the current implementation perfectly intuitive and I wouldn´t want it any other way... it models the underlying hardware, just the way it should be. Sometimes due to bad coding standards I´m forced to write... if((.....long expression with not immediately apparent operator precedence)!=0) ... absolutely appalling, kills readability with extra () etc. doesn´t matter how many years, I was forced to do it, I still cringe every time I see a line like that and itch to rewrite it more readable.The real issue is do you want to have the implicit conversions: 0 => false 1 => true or would you require a cast?The idea of a "true number" and a "false number" doesn't make sense, so yes.
Apr 26 2013
On Thu, 25 Apr 2013 23:01:30 -0700, Walter Bright <newshound2 digitalmars.com> wrote:D tries very hard to avoid the notion of a "better" match. It goes with an exact match, followed by one with implicit conversions. All implicit conversions are considered equally good. Ambiguity is resolved by invoking "partial ordering", which was explained elsewhere in this thread. Partial ordering does not at all consider "better" matches.I think the issue (and I am firmly in the foo(1) => long camp) is that bools are considered better integers than actual integer types (or even floating point types for that matter). I agree that bools can be implicitly cast to and from integers, as a last resort.Once you venture down the path of "better" matches, it's all roses at first, but look at where C++ wound up with it. It didn't intend to arrive there, it inevitably arrived there.bool is true or false. It can be interchangeable with 0 or 1. But if it's overloaded with an integral or otherwise numeric type (float, double, etc), then the numeric type should be chosen first, or ambiguity flagged (your choice). The current behavior is as bad as if(); That's not ambiguous, and follows the grammatical rules, why does that deserve a special case and this not?The real issue is do you want to have the implicit conversions: 0 => false 1 => true or would you require a cast?This is irrelevant to the problem. If one wants to pass a boolean literal, they would use true or false, not cast(bool)1 or cast(bool)0. When an implicit cast must be done, and overload selection is at stake, bool should be last on the list of numeric types. I think you are incorrectly making this into a "it has to be this way for consistency" issue, it's not. It's an arbitrary rule, with very little sense involved. -Steve
Apr 26 2013
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.
Apr 27 2013
On Sat, 27 Apr 2013 13:27:39 -0700, Walter Bright <newshound2 digitalmars.com> wrote:On 4/26/2013 11:04 PM, 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. -SteveI 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.
Apr 29 2013
Am 29.04.2013 19:10, schrieb Steven Schveighoffer:On Sat, 27 Apr 2013 13:27:39 -0700, Walter Bright <newshound2 digitalmars.com> wrote:Fully agree, I still not understand what is the issue to support the boolean strong typing other languages do offer. -- PauloOn 4/26/2013 11:04 PM, 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. -SteveI 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.
Apr 29 2013
On 4/29/2013 10:10 AM, Steven Schveighoffer wrote:On Sat, 27 Apr 2013 13:27:39 -0700, Walter Bright <newshound2 digitalmars.com> wrote:Carefully reading your statement, you are still arguing that matching 1 to long should be "better" than matching it to bool.On 4/26/2013 11:04 PM, 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.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.
Apr 29 2013
On Mon, 29 Apr 2013 11:39:27 -0700, Walter Bright <newshound2 digitalmars.com> wrote:On 4/29/2013 10:10 AM, Steven Schveighoffer wrote:Yes, just like it's better matching to long than string. -SteveI 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.
Apr 30 2013
On Tuesday, 30 April 2013 at 14:47:14 UTC, Steven Schveighoffer wrote:Yes, just like it's better matching to long than string. -SteveMore 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
Apr 30 2013
On Tue, 30 Apr 2013 10:43:01 -0700, Rob T <alanb ucora.com> wrote:On Tuesday, 30 April 2013 at 14:47:14 UTC, Steven Schveighoffer wrote: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. -SteveYes, just like it's better matching to long than string. -SteveMore 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.
Apr 30 2013
Am 30.04.2013 20:50, schrieb Steven Schveighoffer:On Tue, 30 Apr 2013 10:43:01 -0700, Rob T <alanb ucora.com> wrote:+1On Tuesday, 30 April 2013 at 14:47:14 UTC, Steven Schveighoffer wrote: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. -SteveYes, just like it's better matching to long than string. -SteveMore 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.
Apr 30 2013
+1 (and give a helpful compiler error with suggested modification)
Apr 30 2013
On Monday, 29 April 2013 at 18:39:27 UTC, Walter Bright wrote:On 4/29/2013 10:10 AM, Steven Schveighoffer wrote: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?On Sat, 27 Apr 2013 13:27:39 -0700, Walter Bright <newshound2 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.
Apr 30 2013
On Friday, 26 April 2013 at 06:01:27 UTC, Walter Bright wrote:On 4/25/2013 10:49 PM, Ali Çehreli wrote: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.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.
Apr 28 2013
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.
Apr 28 2013
On Sunday, 28 April 2013 at 21:17:39 UTC, Walter Bright wrote:On 4/28/2013 1:58 PM, Mehrdad wrote: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?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.
Apr 28 2013
On 04/28/2013 11:22 PM, Mehrdad wrote:On Sunday, 28 April 2013 at 21:17:39 UTC, Walter Bright wrote:He is saying bool is an integral type in D. (i.e. it can be promoted to 'int' in order to support integer arithmetic.)On 4/28/2013 1:58 PM, Mehrdad wrote: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?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.
Apr 28 2013
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.gehr gmx.ch>On 04/28/2013 11:22 PM, Mehrdad wrote:On Sunday, 28 April 2013 at 21:17:39 UTC, Walter Bright wrote:He is saying bool is an integral type in D. (i.e. it can be promoted to 'int' in order to support integer arithmetic.)On 4/28/2013 1:58 PM, Mehrdad wrote: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?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.
Apr 28 2013
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 HaraWell 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
Apr 28 2013
On Sunday, 28 April 2013 at 22:40:33 UTC, Andrei Alexandrescu wrote:On 4/28/13 5:41 PM, kenji hara wrote: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.Yes, as Andrei mentioned, it is sometimes useful. But, at least during overload resolution, it must not occur. Kenji HaraWell 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
Apr 28 2013
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
Apr 28 2013
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?
Apr 28 2013
On Sunday, 28 April 2013 at 22:40:33 UTC, Andrei Alexandrescu wrote:On 4/28/13 5:41 PM, kenji hara wrote:For the same reason, both should call the long overload.Yes, as Andrei mentioned, it is sometimes useful. But, at least during overload resolution, it must not occur. Kenji HaraWell 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.
Apr 29 2013
On Friday, 26 April 2013 at 05:02:50 UTC, Walter Bright wrote:On 4/25/2013 7:54 PM, Kapps wrote:This "feature" never has been useful to me. It has caused bug. Additionally, the behavior is inconsistent : int i = 1; foo(i); // Don't call the bool version.This is just silly. Changing enum defaultVal = 1 to defaultVal = 2 should never result in calling a different overload.This does: ------------------------ import core.stdc.stdio; enum x = 10000; enum y = 40000; int foo(short s) { return 1; } int foo(long s) { return 2; } void main() { printf("%d\n", foo(x)); printf("%d\n", foo(y)); } ------------------------- A bool is an integer with the range 0..1
Apr 25 2013
On Friday, 26 April 2013 at 06:16:29 UTC, deadalnix wrote:On Friday, 26 April 2013 at 05:02:50 UTC, Walter Bright wrote:+1A bool is an integer with the range 0..1This "feature" never has been useful to me.
Apr 26 2013
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!It has caused bug.The bug is not providing an overload for int.Additionally, the behavior is inconsistent : int i = 1; foo(i); // Don't call the bool version.It is not inconsistent - you forgot a foo(int) overload. '1' is an int. If you don't supply and int overload, it must implicitly convert, and those conversions are considered equivalent.
Apr 26 2013
On Friday, 26 April 2013 at 08:03:14 UTC, Walter Bright wrote:On 4/25/2013 11:16 PM, deadalnix wrote:Because bool value range should be used as a failover mecanism IMO. And bool shouldn't be considered as an integral.This "feature" never has been useful to me.It has been useful to me. So there!It has caused bug.The bug is not providing an overload for int.Additionally, the behavior is inconsistent : int i = 1; foo(i); // Don't call the bool version.It is not inconsistent - you forgot a foo(int) overload. '1' is an int. If you don't supply and int overload, it must implicitly convert, and those conversions are considered equivalent.
Apr 26 2013
On Friday, 26 April 2013 at 08:03:14 UTC, Walter Bright wrote:On 4/25/2013 11:16 PM, deadalnix wrote:If you want an int to behave like a bool, then by all means go ahead and write the code yourself, I don't want the compiler to do it for me in a silent manner.This "feature" never has been useful to me.It has been useful to me. So there!That kind of nonintuitive requirement is easily overlooked.It has caused bug.The bug is not providing an overload for int.Seriously, let's fix this once and for all. Bool is bool, it's not int and never should have been. I don't understand why we're having this debate. --rtAdditionally, the behavior is inconsistent : int i = 1; foo(i); // Don't call the bool version.It is not inconsistent - you forgot a foo(int) overload. '1' is an int. If you don't supply and int overload, it must implicitly convert, and those conversions are considered equivalent.
Apr 26 2013
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: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.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!
Apr 28 2013
On 04/26/2013 07:02 AM, Walter Bright wrote:A bool is an integer with the range 0..1This is True for the type but for the actual code it looks different. There 0 == false. and everything else is true. import std.stdio; void main() { if(10) { writefln("%d is also true", 10); } } if(value) proberly becomes: cmp value, 0 jne ifblock Anyway, I think no implicit casts would be wonderful, sure everybody would hate it at first but than...
Apr 26 2013
On 4/26/2013 5:01 AM, Robert Schadek wrote:Anyway, I think no implicit casts would be wonderful, sure everybody would hate it at first but than...I've used a language with no implicit casts. It didn't get better, and I have an enduring dislike of it.
Apr 26 2013
On 04/26/2013 09:11 PM, Walter Bright wrote:On 4/26/2013 5:01 AM, Robert Schadek wrote:What language? (In my experience it actually gets better.)Anyway, I think no implicit casts would be wonderful, sure everybody would hate it at first but than...I've used a language with no implicit casts. It didn't get better, and I have an enduring dislike of it.
Apr 26 2013
On 4/26/2013 1:16 PM, Timon Gehr wrote:On 04/26/2013 09:11 PM, Walter Bright wrote:An early Pascal.On 4/26/2013 5:01 AM, Robert Schadek wrote:What language? (In my experience it actually gets better.)Anyway, I think no implicit casts would be wonderful, sure everybody would hate it at first but than...I've used a language with no implicit casts. It didn't get better, and I have an enduring dislike of it.
Apr 26 2013
Whatever the choices are of whether bool is a 1-bit integer or a a logical true/false value, this should not happen: enum e = 1; void main() { foo(e); // bool } static e = 1; void main() { foo(e); // long } The reason being that according to the language spec, the constant "1" should be an int. Whether or not it implicitly converts to a bool, this means that "enum e" should have a type of int as well. The actual value shouldn't be taken into account when determining which overload to call, only the type should matter, and an unknown int value should implicitly convert to a long not a bool. Automatic conversion of "1" to bool should only be able to happen at the point where the literal is used if at all: enum bool e = 1; Ideally such an implicit conversion would only apply if it was the only possible valid implicit conversion, so this: foo(1) Should at least warn of the ambiguity. Compile-time conversions based on value rather than type are by definition going to break the type system. Therefore the only way to get "1" to normally be an "int" but automatically convert to a "bool" without being inconsistent is to effectively introduce a new type for the literal "1" which has the desired conversions (the same way that zero has a special type in C/C++ which can convert to both an integer or a pointer). The important thing is that this special type for "1" should never transfer to other things: the type of the literal should be fixed to a normal type at the point where it is used to prevent surprising the user (this is what C/C++ does). At the moment "enum e = 1;" transfers the special properties of "1" to "e" and I think that's more than a little surprising.
Apr 26 2013
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: ubyte b; b = 100; // ok b = 300; // error This has been very successful in reducing the noise of having to insert casts all over the place. For: enum e = 1; then e is a value that is known to be one. Hence VRP applies, and it can be implicitly cast to bool, ubyte, short, etc. For: static e = 1; the compiler cannot assume that e is always 1, hence e is treated as an int that could hold any value. Hence, it cannot be implicitly cast to bool, ubyte, short, etc.Ideally such an implicit conversion would only apply if it was the onlypossible valid implicit conversion, This was how D originally worked. However, it produced a list of foolish errors, and a lot of complaints. The current scheme attempts to resolve ambiguities by doing a "partial ordering" (described elsewhere in this thread). This has been very successful. To make use of overloading, there's no avoiding understanding this. A program that breaks due to different overloadings of: enum e = 1; static x = 1; is misusing overloading just like one that breaks on different overloads of: enum e = 30000; static x = 40000; I.e.: void foo(short) { ... back up my files ... } void foo(long) { ... launch nuclear missiles ... } is a bad program.
Apr 26 2013
On Friday, 26 April 2013 at 21:34:44 UTC, Walter Bright wrote:void foo(short) { ... back up my files ... } void foo(long) { ... launch nuclear missiles ... } is a bad program.The government of North Korea would probably be perfectly happy with this program, but then again, that's a bad government.
Apr 26 2013
On Friday, April 26, 2013 14:34:45 Walter Bright wrote:D has an interesting feature called VRP (value range propagation), where implicit conversion very much depends on the value.VRP is a fantastic feature, but I think that it's coming back to bite us somewhat if foo(1) calls an overload which takes bool. - Jonathan M Davis
Apr 26 2013
On Fri, Apr 26, 2013 at 08:05:45PM -0400, Jonathan M Davis wrote:On Friday, April 26, 2013 14:34:45 Walter Bright 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? } ... } T -- That's not a bug; that's a feature!D has an interesting feature called VRP (value range propagation), where implicit conversion very much depends on the value.VRP is a fantastic feature, but I think that it's coming back to bite us somewhat if foo(1) calls an overload which takes bool.
Apr 26 2013
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.
Apr 27 2013
On Friday, 26 April 2013 at 21:34:44 UTC, Walter Bright wrote:On 4/26/2013 1:59 PM, Diggory wrote:Then perhaps ban VRP on arguments if it affects overloading?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:
Apr 26 2013
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.
Apr 27 2013
On Saturday, April 27, 2013 06:19:29 Maxim Fomin wrote:On Friday, 26 April 2013 at 21:34:44 UTC, Walter Bright wrote: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 DavisOn 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 onthe value. For example:Then perhaps ban VRP on arguments if it affects overloading?
Apr 27 2013
Am 28.04.2013 02:34, schrieb Jonathan M Davis:On Saturday, April 27, 2013 06:19:29 Maxim Fomin wrote:Well, we need material to write "D the good parts" :)On Friday, 26 April 2013 at 21:34:44 UTC, Walter Bright wrote: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 DavisOn 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 onthe value. For example:Then perhaps ban VRP on arguments if it affects overloading?
Apr 27 2013