Is nan in (nan,) correct?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Mar 6 11:43:37 EST 2015


Rustom Mody wrote:

> On Friday, March 6, 2015 at 3:57:12 AM UTC+5:30, rand... at fastmail.us
> wrote:
>> It's been brought up on Stack Overflow that the "in" operator (on
>> tuples, and by my testing on dict and list, as well as dict lookup) uses
>> object identity as a shortcut, and returns true immediately if the
>> object being tested *is* an element of the container. However, the
>> contains operation does not specify whether object identity or equality
>> is to be used. In effect, the built-in container types use a hybrid
>> test: "a is b or a == b".
>> 
>> My question is, is this a *correct* implementation of the operator, or
>> are objects "supposed to" use a basis of equality for these tests?
> 
> nan is an illegal or bogus value.

NANs *represent* bogus values, they aren't bogus themselves.


> As usual legalizing the illegal is always fraught with increasing
> conundrums.
> 
> The most (to me) classic instance of this is denotational semantics.
> In DS one tries to give semantics to programs by mapping programs to
> math-functions across some domains
> 
> However some programs crash. What should be the semantics of such a
> program. We say its a partial function – undefined at the crash-points.
> But partial functions are not nearly as tractable (to mathematicians!) as
> total functions.
> So we invent a bogus value  ⊥ (called bottom) and totalize all functions
> by mapping to this.
> 
> Very nice…
> 
> So nice in fact that we wish to add ⊥ to our programming language
> 
> And now all hell breaks loose because the question x == ⊥ is the halting
> problem.

Oh nonsense. x == ⊥ is easily performed with the equivalent of:

type(x) == BottomType and bit_representation(x) == bit_representation(⊥)



> And people love this problem so much they keep replicating it:
> 
> - C and null (or Pascal/Lisp and Nil)
> [Hoare's billion dollar mistake
> [https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions ]
> - nul in SQL – Should two nuls compare as same or different?
>   There are good (and different!) reasons for both answers
> - Python and None
> - Floats and nans

This is a random grab-bag of unrelated "problems" that differ in their
causes and their consequences. The only thing they have in common is that
Null/Nil/Nul/None/NAN all begin with N, and are all "special" in some
sense.


> My own thoughts on this (not very well thought out, I admit)
> The letter of the IEEE standard talks of nans and their details
> The spirit of the standard is that nans capture exception-al computations
> ie nan represents an exception
> 
> In a language like python with decent exceptions we do not need nans.

Then you are missing the most important use-case for NANs.

Really, do you think that the designers of IEEE-754 actually didn't think of
this? Long before high-level languages like Python started using
exceptions, low-level languages had "traps" that did more or less the same
thing. If all you want is merely to interrupt your calculation the first
time an error occurs, then you just trap the error condition and you're
done.

But IEEE-754 supports *not* interrupting the calculation, but allowing the
error condition to propagate all the way to the end of the calculation.
Instead of peppering your calculation with dozens of checks ("Look Before
You Leap") to avoid triggering a trap, you just perform the calculation,
and then at the end inspect the result and if it is a NAN you can decide
how to handle it ("Easier To Ask Forgiveness Than Permission"). The whole
point of NANs is to avoid traps (exceptions, signals, or whatever you want
to call this interruption) from being triggered. To replace NANs with
exceptions is to miss their whole reason for existence!

And for those who do want an immediate exception, the standard supports that
too, with *signalling NANs*, which are supposed to trap on just about every
operation. A proper IEEE-754 system will allow you to decide which
operations should trap immediately and which don't, it's not a global
all-or-nothing prospect.

Alas, although many (most? all?) FPUs these days support these features,
hardly any high-level language does. You typically cannot even control
these features from C, but have to drop down to assembly. The fine control
that IEEE-754 offers is under-utilized because the language designers don't
support it.



-- 
Steven




More information about the Python-list mailing list