July 03, 2019
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.
July 04, 2019
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.
July 04, 2019
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.
July 04, 2019
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.
July 04, 2019
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
July 04, 2019
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.

July 04, 2019
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.
July 05, 2019
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.
July 04, 2019
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



July 05, 2019
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.