www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - bool <=> int. WTF. (DIP0015)

reply a11e99z <black80 bk.ru> writes:
import std;

enum E : int { zer, one, two };

auto fn( long a ) { writeln( typeof(a).stringof, " ", a ); return 
a; }
auto fn( bool a ) { writeln( typeof(a).stringof, " ", a ); return 
a; }

void main() {
     writeln( typeof(0).stringof, " ", 0.sizeof );
     writeln( typeof(1).stringof, " ", 1.sizeof );
     writeln( typeof(E.two).stringof, " ", E.two.sizeof );

     fn( 0 );
     fn( 1 );
     fn( 2 );
     fn( E.zer );
     fn( E.one );
     fn( E.two );
}


prints:

int 4 int 4 E 4 bool false bool true long 2 bool false bool true long 2 <<<<<<<<<<<<<<<<<<< first WTF? why called with bool? 1 is int32 as D printed. E is at least int2 but with explicitly base type as int it is int32 too. why bool? why D ignores integral promotion that moves to bigger size or unsigned same size? okey. probably bool is int1 and finita la comedia! (one man (Simon?) says that) bool b = 0; writeln( ++b ); // Error: operation not allowed on bool b += 1 second WTF? so, what bool is? is this int1? why others promotes to less size and why disallow ++ for int1? is this a "real" boolean? why others promotes to it? imo - if some datatypes used as condition they implicitly converts to bool - ok - funcs that accept bools should be checked/searched in the end as last choice. in case where exists other alternatives to bool it should be selected. Please make a system for voting. Give to Walter 100 votes but not 99% of all votes as it is now. And let's vote for adequate non brainf*king behavior.
Jul 02
next sibling parent reply 9il <ilyayaroshenko gmail.com> writes:
On Tuesday, 2 July 2019 at 12:06:00 UTC, a11e99z wrote:
 import std;

 enum E : int { zer, one, two };

 [...]
Looks like a serious bug to me. Please report it at https://issues.dlang.org/
Jul 02
next sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
On Tuesday, 2 July 2019 at 13:42:28 UTC, 9il wrote:
 [snip]

 Looks like a serious bug to me. Please report it at 
 https://issues.dlang.org/
According to the section on function overloading [1], this is a "match with implicit conversions." Numeric literals like 0 and 1 can be implicitly converted to bool [2], so that isn't a bug, even if it is confusing in this case. I think people could disagree on whether the enum part of the example is a bug. Maybe more of an enhancement request to have different handling for function overloads with enums? The enum values are being treated like literals instead of as ints. [1] https://dlang.org/spec/function.html#function-overloading [2] https://dlang.org/spec/type.html#bool
Jul 02
next sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Tuesday, 2 July 2019 at 15:10:37 UTC, jmh530 wrote:
 [snip]
Just realized that pretty much exactly this example with enums is in the DIP 1015 text...
Jul 02
prev sibling parent a11e99z <black80 bk.ru> writes:
On Tuesday, 2 July 2019 at 15:10:37 UTC, jmh530 wrote:
 On Tuesday, 2 July 2019 at 13:42:28 UTC, 9il wrote:
 I think people could disagree on whether the enum part of the 
 example is a bug. Maybe more of an enhancement request to have 
 different handling for function overloads with enums? The enum 
 values are being treated like literals instead of as int
for one type called different functions. its very, very, very weird. its impossible in any other langs probably. imo should be fixed. for enums with base types not bool functions with bool should never be called at all
Jul 02
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 02.07.19 15:42, 9il wrote:
 On Tuesday, 2 July 2019 at 12:06:00 UTC, a11e99z wrote:
 import std;

 enum E : int { zer, one, two };

 [...]
Looks like a serious bug to me. Please report it at https://issues.dlang.org/
It is not a bug in the implementation. The attempted spec fix has been turned down: https://forum.dlang.org/post/xkfgbfhhtkiewfqqsvcv forum.dlang.org
Jul 02
prev sibling next sibling parent reply Exil <Exil gmall.com> writes:
On Tuesday, 2 July 2019 at 12:06:00 UTC, a11e99z wrote:
 import std;

 enum E : int { zer, one, two };

 auto fn( long a ) { writeln( typeof(a).stringof, " ", a ); 
 return a; }
 auto fn( bool a ) { writeln( typeof(a).stringof, " ", a ); 
 return a; }

 void main() {
     writeln( typeof(0).stringof, " ", 0.sizeof );
     writeln( typeof(1).stringof, " ", 1.sizeof );
     writeln( typeof(E.two).stringof, " ", E.two.sizeof );

     fn( 0 );
     fn( 1 );
     fn( 2 );
     fn( E.zer );
     fn( E.one );
     fn( E.two );
 }


 prints:

int 4 int 4 E 4 bool false bool true long 2 bool false bool true long 2 <<<<<<<<<<<<<<<<<<< first WTF? why called with bool? 1 is int32 as D printed. E is at least int2 but with explicitly base type as int it is int32 too. why bool? why D ignores integral promotion that moves to bigger size or unsigned same size? okey. probably bool is int1 and finita la comedia! (one man (Simon?) says that) bool b = 0; writeln( ++b ); // Error: operation not allowed on bool b += 1 second WTF? so, what bool is? is this int1? why others promotes to less size and why disallow ++ for int1? is this a "real" boolean? why others promotes to it? imo - if some datatypes used as condition they implicitly converts to bool - ok - funcs that accept bools should be checked/searched in the end as last choice. in case where exists other alternatives to bool it should be selected. Please make a system for voting. Give to Walter 100 votes but not 99% of all votes as it is now. And let's vote for adequate non brainf*king behavior.
https://www.youtube.com/watch?v=cpTAtiboIDs#t=2h17m50s This isn't likely to change. Some more discussion here: https://forum.dlang.org/thread/bareupbeyubtmyorxqcz forum.dlang.org?page=1
Jul 02
parent reply wjoe <invalid example.com> writes:
On Tuesday, 2 July 2019 at 16:24:07 UTC, Exil wrote:
 https://www.youtube.com/watch?v=cpTAtiboIDs#t=2h17m50s

 This isn't likely to change.

 Some more discussion here:

 https://forum.dlang.org/thread/bareupbeyubtmyorxqcz forum.dlang.org?page=1
Technically this is a reply to the video on youtube. A Boolean should be a type to be explicitly incompatible with an int with values of 'true' and 'false' otherwise there is no justification for its existence. Being implemented as an int with a range of 0..1 is an implementation detail. It could just as well be implemented as all bits 1 = false, all bits 0 = true, or -17 = false and 42 = true, or ... . I strongly disagree with the *definition* of int 0..1 because a Boolean isn't a number and is neither 0 nor 1, but it's true or false. A Boolean is an expression of truthfulness. An integer is a number and only related to a Boolean value with regards to the hardware it's implemented on. Why is 0 supposed to be false ? Why is 1 supposed to be true ? And why does D declare that 2 is not a valid Boolean while 2 evaluates to true? On the hardware level it makes sense to have a 'jump if zero' and 'jump if not zero' instruction and implement it that way, but at the higher language level it doesn't - that's the point of being higher level. It comes down to that because it's more performant/efficient/whatever than comparing to any other arbitrary value? Fair enough but that doesn't mean a Boolean false is in fact an integer. I've done TTL electronics, too, and don't get the 5V argument and how that's supposed to be related to Boolean's supposed to be an integer 0..1 - for a 0 isn't plain 0. Anything between 0V and 0.8V is low. Anything from >0.8V to <2.0V is invalid and undefined behavior. Anything between 2.0V and 5.0V is high. Anything >5.0V will, exact threshold depends on the material, eventually destroy the IC. So while we're at the business of translating numbers to bool why does it matter whether it's a float or an int? 0.0f is in the range of low. From that point of view I'd expect assigning 0.0 - 0.8 to bool is false and 2.0 - 5.0 is true and everything else blows up the compiler. If it's not a type it would better be replaced by something like this: alias Boolean = int; immutable Boolean FALSE = 0; immutable Boolean TRUE = ~FALSE; or even better - the C way. Is it 0, or else... This is completely predictable unlike the bool b = void; can be true and false at the same time. The whole point of a Boolean data type is that it's something in its own right and decoupled from the implementation. Otherwise it's a redundancy. But then, IMHO, Boolean is almost always best to be replaced by something more expressive like std.typecons.Flag On that note if there's something that can be removed from the D language, it's bool.
Jul 04
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 4 July 2019 at 15:30:59 UTC, wjoe wrote:
 This is completely predictable unlike the bool b = void; can be 
 true and false at the same time.
Accessing an uninitialized variable results in undefined behavior. There's nothing special about bool here.
Jul 04
parent ag0aep6g <anonymous example.com> writes:
On 04.07.19 17:51, Paul Backus wrote:
 Accessing an uninitialized variable results in undefined behavior. 
For D, the jury is still out on that. https://issues.dlang.org/show_bug.cgi?id=18016 https://github.com/dlang/dlang.org/pull/2260
Jul 04
prev sibling parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Thursday, 4 July 2019 at 15:30:59 UTC, wjoe wrote:
[snip good arguments]

 or even better - the C way. Is it 0, or else...
 This is completely predictable unlike the bool b = void; can be 
 true and false at the same time.
that's the issue. D's bool type follows exactly C (C has bool since C99) and C++ way. bool b; will behave exactly like your bool b = void;
 The whole point of a Boolean data type is that it's something 
 in its own right and decoupled from the implementation. 
 Otherwise it's a redundancy.

 But then, IMHO, Boolean is almost always best to be replaced by 
 something more expressive like std.typecons.Flag

 On that note if there's something that can be removed from the 
 D language, it's bool.
Nope.
Jul 04
next sibling parent Era Scarecrow <rtcvb32 yahoo.com> writes:
On Thursday, 4 July 2019 at 16:31:11 UTC, Patrick Schluter wrote:
 that's the issue. D's bool type follows exactly C (C has bool 
 since C99) and C++ way.
Could always make a new type that's strictly 1 bit and not implicitly converted with only 2 possible values. Then the compiler may use the original bool or the new bool, depending on compiling optimizations if it would make a difference. But honestly, i kinda like the C/C++ way, since it then makes it easy to do if statements for results and pointers rather than explicitly comparing != null on every pointer/use of it. And you're basically ensuring non-zero and non-false in that case. Opcode-wise, usually a simple bool check is 'test eax,eax' which will give a Z/NZ flag and you do a jump (jz/jnz) from there. Having it behave like C/C++ is... well... quite wide-reaching and accepted. I don't see the point in deviating from that.
Jul 04
prev sibling next sibling parent reply Exil <Exil gmall.com> writes:
On Thursday, 4 July 2019 at 16:31:11 UTC, Patrick Schluter wrote:
 that's the issue. D's bool type follows exactly C (C has bool 
 since C99) and C++ way.
 bool b; will behave exactly like your bool b = void;
It doesn't have the same behavior. Currently DMD's codegen is bad, sometimes it checks the entire byte value and other times it only checks the first bit. All C/C++ compilers I've used check the entire value, consistently.
Jul 04
parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Friday, 5 July 2019 at 03:10:06 UTC, Exil wrote:
 On Thursday, 4 July 2019 at 16:31:11 UTC, Patrick Schluter 
 wrote:
 that's the issue. D's bool type follows exactly C (C has bool 
 since C99) and C++ way.
 bool b; will behave exactly like your bool b = void;
It doesn't have the same behavior. Currently DMD's codegen is bad, sometimes it checks the entire byte value and other times it only checks the first bit. All C/C++ compilers I've used check the entire value, consistently.
if the codegen does something like (x & 1) then it is indeed a BUG and should be corrected.
Jul 05
next sibling parent wjoe <invalid example.com> writes:
On Friday, 5 July 2019 at 09:04:26 UTC, Patrick Schluter wrote:
 On Friday, 5 July 2019 at 03:10:06 UTC, Exil wrote:
 On Thursday, 4 July 2019 at 16:31:11 UTC, Patrick Schluter 
 wrote:
 that's the issue. D's bool type follows exactly C (C has bool 
 since C99) and C++ way.
 bool b; will behave exactly like your bool b = void;
It doesn't have the same behavior. Currently DMD's codegen is bad, sometimes it checks the entire byte value and other times it only checks the first bit. All C/C++ compilers I've used check the entire value, consistently.
if the codegen does something like (x & 1) then it is indeed a BUG and should be corrected.
No. If bool is really a 1 bit integer then this generated code is correct. Since there are no 1 bit registers the compiler must use a bigger one for a 1 bit integer. The resulting behavior when storing values > 1 into this int1 is akin to an integer overflow hence it's not a bug.
Jul 05
prev sibling parent reply lithium iodate <whatdoiknow doesntexist.net> writes:
On Friday, 5 July 2019 at 09:04:26 UTC, Patrick Schluter wrote:
 On Friday, 5 July 2019 at 03:10:06 UTC, Exil wrote:
 On Thursday, 4 July 2019 at 16:31:11 UTC, Patrick Schluter 
 wrote:
 that's the issue. D's bool type follows exactly C (C has bool 
 since C99) and C++ way.
 bool b; will behave exactly like your bool b = void;
It doesn't have the same behavior. Currently DMD's codegen is bad, sometimes it checks the entire byte value and other times it only checks the first bit. All C/C++ compilers I've used check the entire value, consistently.
if the codegen does something like (x & 1) then it is indeed a BUG and should be corrected.
Bug because it is inefficient or incorrect? To the best of my knowledge C does only mandate that _Bool must be able to store 0 and 1, and imposes no requirements on how other representations have to be treated. GCC treats _Bool as having 2 valid representations and 254 trap representations, so x == 1, x & 1 and x > 0 are all necessarily equivalent given this assumption. Not sure about Clang, in my quick test it always only checked the least significant bit. Does D really not have more specific requirements for bool? (Does D even allow anything to have trap representations? There doesn't really seem to be any info on that)
Jul 05
parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Friday, 5 July 2019 at 21:45:00 UTC, lithium iodate wrote:
 On Friday, 5 July 2019 at 09:04:26 UTC, Patrick Schluter wrote:
 On Friday, 5 July 2019 at 03:10:06 UTC, Exil wrote:
 On Thursday, 4 July 2019 at 16:31:11 UTC, Patrick Schluter 
 wrote:
 that's the issue. D's bool type follows exactly C (C has 
 bool since C99) and C++ way.
 bool b; will behave exactly like your bool b = void;
It doesn't have the same behavior. Currently DMD's codegen is bad, sometimes it checks the entire byte value and other times it only checks the first bit. All C/C++ compilers I've used check the entire value, consistently.
if the codegen does something like (x & 1) then it is indeed a BUG and should be corrected.
Bug because it is inefficient or incorrect? To the best of my knowledge C does only mandate that _Bool must be able to store 0 and 1, and imposes no requirements on how other representations have to be treated.
The standard says that other bit representations in the bool variable (uninitialised) is "undefined behaviour", so there is no further point in discussing about the validity of what the compilers do after that.
 GCC treats _Bool as having 2 valid representations and 254 trap 
 representations, so x == 1, x & 1 and x > 0 are all necessarily 
 equivalent given this assumption. Not sure about Clang, in my 
 quick test it always only checked the least significant bit.

 Does D really not have more specific requirements for bool? 
 (Does D even allow anything to have trap representations? There 
 doesn't really seem to be any info on that)
I played around a bit on godbolt and indeed the only compiler doing the (x & 1) test is llvm in non-optimized code, be it via ldc or via clang in C and C++. When optimizing it generates code that is more or less same as the other compilers but tries in most cases to only check the value of bit 0. The other compilers are all over the place and sometimes they will generate code that assumes the value is only in bit 0, sometimes not, i.e. any non null value in the register will be seen as true and in other cases not. Conclusion: as the C standard says, undefined behaviour and anything can happen.
Jul 05
prev sibling parent wjoe <invalid example.com> writes:
On Thursday, 4 July 2019 at 16:31:11 UTC, Patrick Schluter wrote:
 On Thursday, 4 July 2019 at 15:30:59 UTC, wjoe wrote:
 [snip good arguments]

 or even better - the C way. Is it 0, or else...
 This is completely predictable unlike the bool b = void; can 
 be true and false at the same time.
that's the issue. D's bool type follows exactly C (C has bool since C99) and C++ way. bool b; will behave exactly like your bool b = void;
I wouldn't know. I've used C before that came to pass. But from what I read online it doesn't behave exactly the same way. Like not at all. But for clarification. What I was referring to was using an integer in place of a Boolean.
 The whole point of a Boolean data type is that it's something 
 in its own right and decoupled from the implementation. 
 Otherwise it's a redundancy.

 But then, IMHO, Boolean is almost always best to be replaced 
 by something more expressive like std.typecons.Flag

 On that note if there's something that can be removed from the 
 D language, it's bool.
Nope.
Yes.
Jul 05
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, July 2, 2019 6:06:00 AM MDT a11e99z via Digitalmars-d wrote:
 import std;

 enum E : int { zer, one, two };

 auto fn( long a ) { writeln( typeof(a).stringof, " ", a ); return
 a; }
 auto fn( bool a ) { writeln( typeof(a).stringof, " ", a ); return
 a; }

 void main() {
      writeln( typeof(0).stringof, " ", 0.sizeof );
      writeln( typeof(1).stringof, " ", 1.sizeof );
      writeln( typeof(E.two).stringof, " ", E.two.sizeof );

      fn( 0 );
      fn( 1 );
      fn( 2 );
      fn( E.zer );
      fn( E.one );
      fn( E.two );
 }


 prints:

 int 4
 int 4
 E 4
 bool false
 bool true
 long 2
 bool false
 bool true
 long 2
 <<<<<<<<<<<<<<<<<<<

 first WTF?
 why called with bool? 1 is int32 as D printed. E is at least int2
 but with explicitly base type as int it is int32 too.
 why bool?
 why D ignores integral promotion that moves to bigger size or
 unsigned same size?

 okey. probably bool is int1 and finita la comedia! (one man
 (Simon?) says that)

 bool b = 0;
 writeln( ++b ); // Error: operation not allowed on bool b += 1

 second WTF?
 so, what bool is?
 is this int1? why others promotes to less size and why disallow
 ++ for int1?
 is this a "real" boolean? why others promotes to it?

 imo
 - if some datatypes used as condition they implicitly converts to
 bool - ok
 - funcs that accept bools should be checked/searched in the end
 as last choice. in case where exists other alternatives to bool
 it should be selected.

 Please make a system for voting. Give to Walter 100 votes but not
 99% of all votes as it is now. And let's vote for adequate non
 brainf*king behavior.
Basically, unlike most of us, Walter doesn't see any real difference between a bit and a bool even conceptually and thus thinks bool should just be a one bit integer type. So, for the most part, that's actally how bool works in D. At some point, either someone convinced him to make ++ illegal on bools or managed to get a PR in that did, and as I understand it, he regrets that that happened. DIP 1015 was proposed to fix how bool works so that it's no longer treated like an integer type, but Walter and Andrei rejected it. It's been discussed to death already, and it's clearly not going to change. As is the case with many (most?) languages, ultimately, language decisions in D are not a democracy. D is Walter's language, and he has the final say. He frequently has made great decisions with D. Many of us do not think that he did in particular this case, but it's still his decision, and it's quite clear at this point that he's not going to change his mind on this topic. So, if you want to use D, you're basically just going to have to learn to put up with the idea that bool is effectively bit. - Jonathan M Davis
Jul 02
parent reply Les De Ridder <les lesderid.net> writes:
On Tuesday, 2 July 2019 at 17:04:24 UTC, Jonathan M Davis wrote:
 On Tuesday, July 2, 2019 6:06:00 AM MDT a11e99z via 
 Digitalmars-d wrote:
 [...]
Basically, unlike most of us, Walter doesn't see any real difference between a bit and a bool even conceptually and thus thinks bool should just be a one bit integer type. So, for the most part, that's actally how bool works in D. At some point, either someone convinced him to make ++ illegal on bools or managed to get a PR in that did, and as I understand it, he regrets that that happened. DIP 1015 was proposed to fix how bool works so that it's no longer treated like an integer type, but Walter and Andrei rejected it. It's been discussed to death already, and it's clearly not going to change. As is the case with many (most?) languages, ultimately, language decisions in D are not a democracy. D is Walter's language, and he has the final say. He frequently has made great decisions with D. Many of us do not think that he did in particular this case, but it's still his decision, and it's quite clear at this point that he's not going to change his mind on this topic. So, if you want to use D, you're basically just going to have to learn to put up with the idea that bool is effectively bit. - Jonathan M Davis
I'm new to this discussion, but: Can we fix the implementation and the spec, then? Walter's opinion is clear, so can we move on? People are still free to write a new DIP to convince the language maintainers, but the current state of bool seems inconsistent. This is in the spec[1] but fails for bool: assert(T.max + 1 == T.min, T.stringof); assert(T.min - 1 == T.max, T.stringof); The spec also doesn't[2] consider `true` and `false` to be integer literals, yet they are of type bool and they can be used as the rhs of an int assignment. The grammar currently doesn't even consider them to be literals[3]. Why do complement expressions[4] not work on bool? To me something feels clearly wrong here. [1] https://dlang.org/spec/expression.html#add_expressions (paragraph 7) [2] https://dlang.org/spec/lex.html#IntegerLiteral [3] https://dlang.org/spec/grammar.html#PrimaryExpression [4] https://dlang.org/spec/expression.html#complement_expressions
Jul 02
next sibling parent reply Zoadian <no no.no> writes:
On Tuesday, 2 July 2019 at 17:43:27 UTC, Les De Ridder wrote:
 On Tuesday, 2 July 2019 at 17:04:24 UTC, Jonathan M Davis wrote:
 [...]
Can we fix the implementation and the spec, then?
+1 Either make bool a real boolean type and disallow implicit conversions, or make it a true 1-bit integer type that actually behaves like all the other int types. It's confusing as heck right now.
Jul 03
parent reply a11e99z <black80 bk.ru> writes:
On Wednesday, 3 July 2019 at 07:47:26 UTC, Zoadian wrote:
 On Tuesday, 2 July 2019 at 17:43:27 UTC, Les De Ridder wrote:
 On Tuesday, 2 July 2019 at 17:04:24 UTC, Jonathan M Davis 
 wrote:
 [...]
Can we fix the implementation and the spec, then?
+1 Either make bool a real boolean type and disallow implicit conversions, or make it a true 1-bit integer type that actually behaves like all the other int types. It's confusing as heck right now.
I vote for real boolean and disallow only implicit conversions to bool for enums:NotBool and consider option conversions to bool for byte/int/char/long/real/any arithmetics at last when no other options. selection for fn(8-7) that prefers fn(bool) instead fn(long) looks weird and incomprehensible and looks more weird when fn(9-7) prefers fn(long) - for one type arg selects two different funcs. well, we used int literals expliciltly here. what to do when some unpredictable const folding will give to us 0,1,2? sit and debug. why and for what? if adds to sample fn( byte a ) { ... } than for enums and const 2 (or const foldings that gives 2) invokes byte version. why again? why compiler fucks the Integer Promotions https://dlang.org/spec/type.html#integer-promotions and next Usual Arithmetic Conversions? why choose byte or bool version for 8 that is int32? why choose byte or bool version for 8-7 that is int32? why try to look for int32 arithmetics less size options? why adding fn( int1/8/16 ) changes logic of program so much? pleeease make adequate decision (my version of such decision): - enums with NoBool base type don't convert to bool implicitly at all. enums with intXX base type supports implicit conversion to intXX but don't consider after it 2nd implicit conversion to bool if (DayOfWeek.tue) ... // WTF? (by the way Tuesday is 3rd day of week(0,1,2=3rd) for USA/Canada/Japan and 2nd(0,1=2nd) for others) - don't consider implicitly less size version. - for one type make call only same one version of function that follow IP rules for ever. // fn(8-7) and fn(9-7) calls only fn(long) for sample - consider bool option last. - (can be discussed) any arithmetics for fundamental ints (not for user types with user ops) lesser that 32-bit gives int32. for ever. 100i8 + 100i16 = 200i32 - add suffixes to integer literals u8/u16/u32/u64/u128 and i8/../i128 (last for cent & ucent) that can allow select func for literals without explicit cast fn( cast( byte )100 ); // calls fn( byte ) fn( 100i8 ); // same totally, for int32 try to use long/ulong/double/real version than try to use bool version and don't try to use less size versions implicitly. implicit conversion for int32 to int1/int8/uint16 are prohibited.
Jul 03
parent Dejan Lekic <dejan.lekic gmail.com> writes:
On Wednesday, 3 July 2019 at 12:22:36 UTC, a11e99z wrote:
 I vote for real boolean
 and disallow only implicit conversions to bool for enums:NotBool
 and consider option conversions to bool for 
 byte/int/char/long/real/any arithmetics at last when no other 
 options.
I say we keep it as it is, but go back to the old days, and call it a "bit" not "boolean", and make it an integer type with all expected implicit conversions.
Jul 04
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, July 2, 2019 11:43:27 AM MDT Les De Ridder via Digitalmars-d 
wrote:
 On Tuesday, 2 July 2019 at 17:04:24 UTC, Jonathan M Davis wrote:
 On Tuesday, July 2, 2019 6:06:00 AM MDT a11e99z via

 Digitalmars-d wrote:
 [...]
Basically, unlike most of us, Walter doesn't see any real difference between a bit and a bool even conceptually and thus thinks bool should just be a one bit integer type. So, for the most part, that's actally how bool works in D. At some point, either someone convinced him to make ++ illegal on bools or managed to get a PR in that did, and as I understand it, he regrets that that happened. DIP 1015 was proposed to fix how bool works so that it's no longer treated like an integer type, but Walter and Andrei rejected it. It's been discussed to death already, and it's clearly not going to change. As is the case with many (most?) languages, ultimately, language decisions in D are not a democracy. D is Walter's language, and he has the final say. He frequently has made great decisions with D. Many of us do not think that he did in particular this case, but it's still his decision, and it's quite clear at this point that he's not going to change his mind on this topic. So, if you want to use D, you're basically just going to have to learn to put up with the idea that bool is effectively bit. - Jonathan M Davis
I'm new to this discussion, but: Can we fix the implementation and the spec, then? Walter's opinion is clear, so can we move on? People are still free to write a new DIP to convince the language maintainers, but the current state of bool seems inconsistent. This is in the spec[1] but fails for bool: assert(T.max + 1 == T.min, T.stringof); assert(T.min - 1 == T.max, T.stringof); The spec also doesn't[2] consider `true` and `false` to be integer literals, yet they are of type bool and they can be used as the rhs of an int assignment. The grammar currently doesn't even consider them to be literals[3]. Why do complement expressions[4] not work on bool? To me something feels clearly wrong here. [1] https://dlang.org/spec/expression.html#add_expressions (paragraph 7) [2] https://dlang.org/spec/lex.html#IntegerLiteral [3] https://dlang.org/spec/grammar.html#PrimaryExpression [4] https://dlang.org/spec/expression.html#complement_expressions
I don't know exactly what the spec should say. Depending on what the issues are, fixing it could require Walter's input, but there's no question that the spec needs to say exactly how things work, and it's possible that some implementation changes would be merited to make things more consistent even if it doesn't involve fixing bool the way many of us would like (though implementation changes quickly get into DIP territory). Walter and Andrei have already talked about how the spec needs to be improved such that it's more on par with what you have with a language like C++, but specs really aren't something that Walter's good at, which is a lot of why we don't have a better spec. So, if you have improvements for the spec, feel free to create PRs. - Jonathan M Davis
Jul 04
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/4/2019 10:47 PM, Jonathan M Davis wrote:
 Walter and Andrei
 have already talked about how the spec needs to be improved such that it's
 more on par with what you have with a language like C++, but specs really
 aren't something that Walter's good at, which is a lot of why we don't have
 a better spec. So, if you have improvements for the spec, feel free to
 create PRs.
I can't get anyone to pull my spec improvements, so my work on that just kinda ran out of steam. https://github.com/dlang/dlang.org/pulls/WalterBright
Jul 05
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Saturday, July 6, 2019 12:10:50 AM MDT Walter Bright via Digitalmars-d 
wrote:
 On 7/4/2019 10:47 PM, Jonathan M Davis wrote:
 Walter and Andrei
 have already talked about how the spec needs to be improved such that
 it's more on par with what you have with a language like C++, but specs
 really aren't something that Walter's good at, which is a lot of why we
 don't have a better spec. So, if you have improvements for the spec,
 feel free to create PRs.
I can't get anyone to pull my spec improvements, so my work on that just kinda ran out of steam. https://github.com/dlang/dlang.org/pulls/WalterBright
I suspect that almost no one pays attention to PRs for the spec, meaning that the number of reviewers is even lower than it is for other repos, and we already have a problem with too few people reviewing stuff in general. I really should figure out how to find more time to spend on stuff like this. - Jonathan M Davis
Jul 05
prev sibling parent reply Rob T <alanb ucora.com> writes:
Sorry old thread I know, but I just got hit by an implicit bool 
to long conversion bug today, it's been a recurring theme over 
the years, so I checked in to see if anything had finally been 
changed to address the recurring bool issue and found this thread 
which is relatively recent, and also DIP 1015 that was rejected.

Perhaps the best solution, is rather than attempting to change 
what are deeply ingrained and polarised concepts surrounding the 
existing quasi bool/integral type, is a DIP proposing the 
addition of a new formally defined boolean type that would leave 
the existing bool type in place unchanged, no compromises have to 
be made, and no legacy code will have to be broken.

Any thoughts on if there may be at least some possible open 
minded support by the two guys who have the veto power?
Sep 17
next sibling parent Daniel Kozak <kozzi11 gmail.com> writes:
On Wed, Sep 18, 2019 at 8:10 AM Rob T via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 Sorry old thread I know, but I just got hit by an implicit bool
 to long conversion bug today, it's been a recurring theme over
 the years, so I checked in to see if anything had finally been
 changed to address the recurring bool issue and found this thread
 which is relatively recent, and also DIP 1015 that was rejected.

 Perhaps the best solution, is rather than attempting to change
 what are deeply ingrained and polarised concepts surrounding the
 existing quasi bool/integral type, is a DIP proposing the
 addition of a new formally defined boolean type that would leave
 the existing bool type in place unchanged, no compromises have to
 be made, and no legacy code will have to be broken.

 Any thoughts on if there may be at least some possible open
 minded support by the two guys who have the veto power?
You can do this on your own, just make your own Boolean type, or it could be added to Phobos, in theory it is there already: https://dlang.org/phobos/std_typecons.html#.Flag.Flag
Sep 18
prev sibling next sibling parent Daniel Kozak <kozzi11 gmail.com> writes:
On Wed, Sep 18, 2019 at 10:06 AM Daniel Kozak <kozzi11 gmail.com> wrote:
 You can do this on your own, just make your own Boolean type, or it
 could be added to Phobos, in theory it is there already:
 https://dlang.org/phobos/std_typecons.html#.Flag.Flag
import std.stdio; import std.typecons; alias MyBool = Flag!"mybool"; alias True = Flag!"mybool".yes; alias False = Flag!"mybool".no; void main() { MyBool a = True; writeln(a); }
Sep 18
prev sibling parent Daniel Kozak <kozzi11 gmail.com> writes:
On Wed, Sep 18, 2019 at 10:13 AM Daniel Kozak <kozzi11 gmail.com> wrote:
...
 alias MyBool = Flag!"mybool";
 alias True = Flag!"mybool".yes;
 alias False = Flag!"mybool".no;
 ...
alias MyBool = Flag!"mybool"; alias True = MyBool.yes; alias False = MyBool.no;
Sep 18