bearophile wrote:
Don:
This conversion seems to be confusing, bug prone, and not useful. Can we
just get rid if it?
So let me understand better the situation.
FP can be: various kinds of NaN, +0.0, -0.0, +infinite, -infinite, and normal
numbers.
The language designers have to decide what to do for those various values in an
instruction like if(x).
At the moment in D NaNs are true, +0.0 and -0.0 are false, and the other values
are true.
Even that's not completely clear. Read the bug report. Sometimes NaNs
are true, sometimes not!
Considering NaN as true looks like an arbitrary decision, but in general NaN
means not a value, so it's not zero nor different from zero. So probably
if(NaN) has to be a runtime error. I think that's what happens when NaNs are
set as signalling.
Your solution is to forbid implicit and explicit casts of floating points to boolean values, because the choice of the true/false values is arbitrary,
Yes.
if(x) normally checks to see if x is "null". But for FP, there are two
different forms of "null", and checking only one of them makes little sense.
and because I think you are saying that packing normal values and NaNs
as true is not meaningful in real programs.
No, I'm not saying that at all. I'm saying that this operation is
extremely subtle, and the syntax gives you a false sense of security.
BTW, once you change if(x) into if (x == 0), you're may ask a second
question: "do I mean exact equality, or should this really be: if
(fabs(x)<= TOLERANCE)" ?
Disabling conversions from FP to bools seems like able to break generic code. If I have a function template that can accept an int or FP and contains an if(x) it can't compile if the type of x is a FP.
The current behaviour breaks generic code, too.
Then if x is a class, then if (x) is true if x has been initialized.
But if x is floating point, if (x) is true if x hasn't been initialized!
This is arguably the main use for `if (x)`.
Note that writing generic code that is correct for both FP and ints is
very difficult. There are so many cases where the same syntax has
different semantics.
This can be solved writing if(x==0) that works with both ints and FPs (and it's true for +0.0 and -0.0).
Exactly. I think this is almost always superior.
In D some people have proposed to change the semantics of the "is" operator, to
make it more useful and tidy, so if you want to know if x is a NaN you can then write
if(x is nan).
That won't work in this case, unless you make nan a keyword. There are
2^^62 different NaNs, so a bitwise comparison will not work.