I get the idea behind NaN != NaN, but has there ever been any instance where this design decision has made practical code better instead of becoming a tripping hazard and requiring extensive special casing?
I'm also not a fan of the other property that NaN evaluates to false for all three of <, > and =, even though I don't have a good idea what to do otherwise.
I think as programmers, we usually assume that "not (a > b)" implies "a <= b" and vice-versa and often rely on that assumption implicitly. NaN breaks that assumption, which could lead to unexpected behavior.
Consider something like this (in JS) :
function make_examples(num_examples) {
if (num_examples <= 0) {
throw Error("num_examples must be 1 or more");
}
const examples = [];
for (let i = 0; i < num_examples; i++) {
examples.push(make_example(i));
}
// we assume that num_examples >= 1 here, so the loop ran at least once and the array cannot be empty.
postprocess_first_example(examples[0]); // <-- (!)
return examples;
}
If somehow num_examples were NaN, the (!) line would fail unexpectedly because the array would be empty.
I don't understand what your example has to do with the NaN != NaN case. You're not comparing NaN to NaN anywhere in it.
No, sorry. That post was kind of two things rolled into one.
The example was about comparing NaN with ordinary numbers, not with itself.
In the example, both "num_examples <= 0" and "0 < num_examples" evaluate to false, which is mathematically correct but leaves the function in an inconsistent state.