www.digitalmars.com         C & C++   DMDScript  

digitalmars.dip.ideas - deprecate boolean evaluation of floating point and character types

reply Basile B. <b2.temp gmx.com> writes:
Generally there is a strong correlation between default 
initialization and boolean evaluation to `false`. Excepted for 
floating point and characters types :

```d
void main(string[] args)
{
     void* v;
     assert(!v);
     int s32;
     assert(!s32);
     long s64;
     assert(!s64);

     class C {}
     C c;
     assert(!c);

     struct S { bool opCast(T)(){return true;} }
     S s;
     assert(s);

     // etc ...

     float f64;
     assert(!f64);
}
```

instead of an assertion failure what we should get is rather a 
message such as

    error, cannot evaluate `f64` to a `bool`
Apr 30
next sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
Characters are quite often compared against zero when doing string 
handling in C without the binary expression. For this reason I would not 
want to see this changed.



Now floats on the other hand... there is no clear truthiness value 
associated with them, unless IEEE-754 defines one (it doesn't appear to 
for 2008 version).

C23 appears to not define if a floating point type can even convert to 
bool, although it does mention bool as not being supported in multiple 
places.
Apr 30
next sibling parent Daniel N <no public.email> writes:
On Tuesday, 30 April 2024 at 18:09:22 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 Characters are quite often compared against zero when doing 
 string handling in C without the binary expression. For this 
 reason I would not want to see this changed.



 Now floats on the other hand... there is no clear truthiness 
 value associated with them, unless IEEE-754 defines one (it 
 doesn't appear to for 2008 version).

 C23 appears to not define if a floating point type can even 
 convert to bool, although it does mention bool as not being 
 supported in multiple places.
I think the most useful conversion would be. NaN -> false because that corresponds to .init Futhermore you can't simply use == to compare with NaN you need to call isNan(), which complicates writing generic code.
Apr 30
prev sibling parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Tuesday, 30 April 2024 at 18:09:22 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 Characters are quite often compared against zero when doing 
 string handling in C without the binary expression. For this 
 reason I would not want to see this changed.
D has the philosophy that valid C code should either behave the same in C as in D, or give an error (c.f. integer promotion rules). It is reasonable to make misleading behaviour like this an error.
Apr 30
parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 01/05/2024 3:45 PM, Nicholas Wilson wrote:
 On Tuesday, 30 April 2024 at 18:09:22 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 Characters are quite often compared against zero when doing string 
 handling in C without the binary expression. For this reason I would 
 not want to see this changed.
D has the philosophy that valid C code should either behave the same in C as in D, or give an error (c.f. integer promotion rules). It is reasonable to make misleading behaviour like this an error.
Both C and D have the same behavior for characters. ```c #include <stdio.h> int main() { char c = 0; if (c) { printf("+\n"); } return 0; } ``` No output. ```d import core.stdc.stdio; void main() { char c = 0; if (c) { printf("+\n"); } } ``` No output.
Apr 30
prev sibling next sibling parent reply Nick Treleaven <nick geany.org> writes:
On Tuesday, 30 April 2024 at 17:01:42 UTC, Basile B. wrote:
 Generally there is a strong correlation between default 
 initialization and boolean evaluation to `false`.
But the meaning of boolean evaluation of a number is to check if it is non-zero. That is well established from C.
 instead of an assertion failure what we should get is rather a 
 message such as

    error, cannot evaluate `f64` to a `bool`
Why break D code that was written with the non-zero test expectation? Why make porting from C harder yet still allow non-zero tests for integers? Wouldn't that be more confusing?
May 01
next sibling parent Basile B. <b2.temp gmx.com> writes:
On Wednesday, 1 May 2024 at 10:01:29 UTC, Nick Treleaven wrote:
 On Tuesday, 30 April 2024 at 17:01:42 UTC, Basile B. wrote:
 Generally there is a strong correlation between default 
 initialization and boolean evaluation to `false`.
But the meaning of boolean evaluation of a number is to check if it is non-zero. That is well established from C.
 instead of an assertion failure what we should get is rather a 
 message such as

    error, cannot evaluate `f64` to a `bool`
Why break D code that was written with the non-zero test expectation? Why make porting from C harder yet still allow non-zero tests for integers? Wouldn't that be more confusing?
This idea is a preliminary work for something bigger: I'd like to propose a DIP for inline variable declarations. For them I have the feeling that char.init and {float|double|real}.init would not work very well. I'm not 100%s sure. I'd say that it's not worth discuting this anymore for now.
May 06
prev sibling next sibling parent Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Wednesday, 1 May 2024 at 10:01:29 UTC, Nick Treleaven wrote:
 On Tuesday, 30 April 2024 at 17:01:42 UTC, Basile B. wrote:
 Generally there is a strong correlation between default 
 initialization and boolean evaluation to `false`.
But the meaning of boolean evaluation of a number is to check if it is non-zero. That is well established from C.
Not well enough for JavaScript. Just tried it: `Boolean(0/0)` gives `false`. Deprecating floating-point to `bool` conversions (in conditions or otherwise) would be correct, including `cast(bool)(x)`. What the user wants, usually, is `!isNaN(x) && x != 0.0`. Writing out `x != 0.0` isn’t that hard. Also, `++x` is morally wrong for floating-point types.
May 16
prev sibling parent reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Wednesday, 1 May 2024 at 10:01:29 UTC, Nick Treleaven wrote:
 On Tuesday, 30 April 2024 at 17:01:42 UTC, Basile B. wrote:
 Generally there is a strong correlation between default 
 initialization and boolean evaluation to `false`.
But the meaning of boolean evaluation of a number is to check if it is non-zero. That is well established from C.
Without looking it up, if `x` is `-0.0`, does `!x` evaluate to `true` or `false`? Hint: Negative zero compares equal to zero (`x == 0.0`), but it’s not zero: `x !is 0.0`. Possibly after looking it up, does the answer make sense to you? Even if you’re 100% sure, would you bet most D programmers get it right?
May 16
parent reply Nick Treleaven <nick geany.org> writes:
On Thursday, 16 May 2024 at 18:03:30 UTC, Quirin Schroll wrote:
 On Wednesday, 1 May 2024 at 10:01:29 UTC, Nick Treleaven wrote:
 But the meaning of boolean evaluation of a number is to check 
 if it is non-zero. That is well established from C.
Without looking it up, if `x` is `-0.0`, does `!x` evaluate to `true` or `false`? Hint: Negative zero compares equal to zero (`x == 0.0`), but it’s not zero: `x !is 0.0`. Possibly after looking it up, does the answer make sense to you? Even if you’re 100% sure, would you bet most D programmers get it right?
`-0.0` would convert to integer 0, which in turn is false. When I said non-zero, that is well defined for integers. So I'm not sure why you think it's surprising that `!-0.0` is true.
May 16
parent Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Thursday, 16 May 2024 at 20:36:17 UTC, Nick Treleaven wrote:
 On Thursday, 16 May 2024 at 18:03:30 UTC, Quirin Schroll wrote:
 On Wednesday, 1 May 2024 at 10:01:29 UTC, Nick Treleaven wrote:
 But the meaning of boolean evaluation of a number is to check 
 if it is non-zero. That is well established from C.
Without looking it up, if `x` is `-0.0`, does `!x` evaluate to `true` or `false`? Hint: Negative zero compares equal to zero (`x == 0.0`), but it’s not zero: `x !is 0.0`. Possibly after looking it up, does the answer make sense to you? Even if you’re 100% sure, would you bet most D programmers get it right?
`-0.0` would convert to integer 0, which in turn is false. When I said non-zero, that is well defined for integers. So I'm not sure why you think it's surprising that `!-0.0` is true.
Because it has a non-zero bit pattern. It does something rather nontrivial.
May 16
prev sibling parent reply Guillaume Piolat <first.name gmail.com> writes:
On Tuesday, 30 April 2024 at 17:01:42 UTC, Basile B. wrote:
 instead of an assertion failure what we should get is rather a 
 message such as

    error, cannot evaluate `f64` to a `bool`
With float you often want to be more specific anyway. Do you mean isFinite? Do you mean !isNaN? Do you mean non-zero? Can't really see a legit use for: if(float) { }
May 10
parent Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Friday, 10 May 2024 at 19:25:45 UTC, Guillaume Piolat wrote:
 On Tuesday, 30 April 2024 at 17:01:42 UTC, Basile B. wrote:
 instead of an assertion failure what we should get is rather a 
 message such as

    error, cannot evaluate `f64` to a `bool`
With float you often want to be more specific anyway. Do you mean isFinite? Do you mean !isNaN? Do you mean non-zero? Can't really see a legit use for: if(float) { }
I wrote that once thinking it meant (!isNaN(x) && x != 0.0), thought I be smart. Introduced a bug. Maybe I overreacted, but I never used implicit conversions to bool in conditions ever. `i != 0`, `x != 0.0`, `ptr !is null`, it’s all so much clearer. Whenever I see `if (x)`, I have to think what it means, unless `x` is a `bool`.
May 16