If exceptions had commonly existed in that environment there's no chance they would have chosen that behavior; comparison against NaN (or any operation with NaN) would have signaled a floating point exception. That is the correct way to handle exceptional conditions.
The only reason to keep NaN's current behavior is to adhere to IEEE, but given that Python has trailblazed a path of correcting arcane mathematical behavior, I definitely see an argument that Python should do the same for NaN, and if it were done Python would be a better language.
If you're going to change behaviour, why have a floating point value
called "nan" at all? Other than being a title for one's grandmother,
what meaning does that string have, and why should it be able to be
cast as floating point?
Lifting from
http://en.wikipedia.org/wiki/NaN a list of things that
can return a NaN (I've removed non-ASCII characters from this
snippet):
* Operations with a NaN as at least one operand.
(you need to bootstrap that somehow, so we can ignore this - it just
means that nan+1 = nan)
* The divisions 0/0 and infinity/infinity
* The multiplications 0*infinity and infinity*0
* The additions +inf + (-inf), (-inf) + +inf and equivalent subtractions
* The standard pow function and the integer exponent pown function
define 0**0, 1**inf, and inf**0 as 1.
* The powr function define all three indeterminate forms as invalid
operations and so returns NaN.
* The square root of a negative number.
* The logarithm of a negative number
* The inverse sine or cosine of a number that is less than -1 or
greater than +1.
Rather than having comparisons with NaN trigger exceptions, wouldn't
it be much cleaner to have all these operations trigger exceptions?
And, I would guess that they probably already do.
NaN has an additional use in that it can be used like a "null
pointer"; a floating-point variable can store 1.0, or 0.000000000005,
or "no there's no value that I'm storing in this variable". Since a
Python variable can contain None instead of a float, this use is
unnecessary too.
So, apart from float("nan"), are there actually any places where real
production code has to handle NaN? I was unable to get a nan by any of
the above methods, except for operations involving inf; for instance,
float("inf")-float("inf") == nan. All the others raised an exception
rather than return nan.
Chris Angelico