top | item 45761062

(no title)

ema | 4 months ago

Maybe the result of NaN === NaN should be neither true nor false but NaB (not a bool).

discuss

order

monkpit|4 months ago

NaN is, by definition, not equal to NaN because they’re not comparable, it does have a definitive Boolean representation - false is correct

zahlman|4 months ago

The concept of NaN long predates the language that uses ===, and is part of a language-agnostic standard that doesn't consider other data types. Any language choosing to treat the equality (regardless of the operator symbol) of NaN differently would be deviating from the spec.

freehorse|4 months ago

Julia evaluates NaN === NaN to true, as long as the underlying bit representations are the same. Eg NaN === -NaN evaluates to false, as happens also with NaNs where for some reason you tinker with their bytes. I think it makes sense that it is so though, regardless that I cannot think of any actual use cases out of doing weird stuff.

disgruntledphd2|4 months ago

In R, NA (which is almost, but not quite like NaN) actually has separate types for each result, so you can have NA_boolean, NA_integer etc. Its super confusing.

getnormality|4 months ago

It is a minor nuisance, but I think there's ultimately a pretty good reason for it.

Old-school base R is less type-sensitive and more "do what I mean", but that leads to slowness and bugs. Now we have the tidyverse, which among many other things provides a new generation of much faster functions with vectorized C implementations under the hood, but this requires them to be more rigid and type-sensitive.

When I want to stick a NA into one of these, I often have to give it the right type of NA, or it'll default to NA_boolean and I'll get type errors.

freehorse|4 months ago

What would an `if (NaB) ... else ...` block do?

Either you throw an exception (and imo it is better to just throw an exception before that already, then) or else what you do determines what NaN === NaN actually evaluates to.

lioeters|4 months ago

Apparently NaN (not a number) becomes false when type-cast to boolean.

  Boolean(NaN)
  ===> false
For a hypothetical NaB (not a boolean), the same behavior seems logical.

  Boolean(NaB)
  ===> false
So the condition `if (NaB)` is false and will fall through to the `else` branch. But..

> what you do determines what NaN === NaN actually evaluates to

I think I disagree with this because it's not about casting to boolean, it's a totally different question of self-identity, or comparing two instances (?) of a value (?!).

From the article:

  typeof NaN
  ===> "number"
For symmetry and consistency:

  typeof NaB
  ===> "boolean"
> NaN is the only value in the whole of JavaScript that isn’t equal to itself .. the concept of NaN is meant to represent a breakdown of calculation

Similarly, NaB would represent a breakdown of true/false condition (somehow) as an exceptional case. Whether it equals itself is a matter of convention or language design, not logic - since it's beyond logic just as NaN is beyond numbers. I would say:

  NaN === NaN
  ===> false

  NaB === NaB
  ===> false
> you throw an exception (and imo it is better..

I agree throwing an exception is better design for such exceptional cases - but we know JavaScript as a cowboy language would rather plow through such ambiguities with idiosyncratic dynamic typing, and let the user figure out the implicit logic (if any).

sophrosyne42|4 months ago

It should throw a compile-time error. Anything like this which allows an invalid or unmeaningful operation to evaluate at compile-time is rife for carrying uncaught errors at run-time.

charcircuit|4 months ago

Or a 3rd option is it should not be allowed similar to dividing by 0.

freehorse|4 months ago

What do you mean "not allowed"? Throwing a compile or runtime error? Many languages allow division by zero, and x/0 typically gives inf unless x is 0, then x/0 gives nan. If x is negative then x/0 gives -inf. Of course this all can get tricky with floats, but mathematically it makes sense to divide by zero (interpreted as a limit).

For NaNs, maybe in some domains it could make sense, but eg I would find it impractical when wanting to select rows based on values in a column and stuff like that.