[Python-Dev] Why is nan != nan? (original) (raw)
Raymond Hettinger raymond.hettinger at gmail.com
Wed Mar 24 23:21:53 CET 2010
- Previous message: [Python-Dev] Why is nan != nan?
- Next message: [Python-Dev] Why is nan != nan?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Mar 24, 2010, at 2:31 PM, Alexander Belopolsky wrote:
""" In this context it doesn't particularly shock me that operations on NaN should cause invariant violations. After all, isn't NaN supposed to mean "not a number"? If it's not a number, it doesn't have to satisfy the properties of numbers. """
This sound like a good, universal reply to "bug reports" about various containers/tools not working with NaNs :-)
Bug report: "Container X or Function Y doesn't behave well when I give it a NaN as an input".
Closed -- Won't fix: "It does not shock me that a NaN violates that tool or container's invariants."
To bring the discussion back on topic for python-dev, I would argue that reflexivity should hold for hashable values. Having it otherwise would lead to unsurmountable problems when storing such values in sets or using them as keys in dictionaries. If x == x is False stays for x = float('nan'), I would argue that hash(float('nan')) should raise NotImplemented or ValueError.
Hashability isn't the only place where you have a problem. Even unordered collections are affected:
class ListBasedSet(collections.Set): ''' Alternate set implementation favoring space over speed and not requiring the set elements to be hashable. ''' def init(self, iterable): self.elements = lst = [] for value in iterable: if value not in lst: lst.append(value) def iter(self): return iter(self.elements) def contains(self, value): return any(value == elem for elem in self.elements) def len(self): return len(self.elements)
n = float('Nan') s = ListBasedSet([n]) n in s # unexpected result False len(s) # expected result 1 len(s & s) # unexpected result 0
If we want to be able to reason about our programs, then we need to rely on equality relations being reflexsive, symmetric, and transitive. Otherwise, containers and functions can't even make minimal guarantees about what they do.
Anything else smells of a Douglas Hofstadter style or Betrand Russell style logic bomb:
- this sentence is a lie
- this object isn't equal to itself
- this is a set containing sets that are not members of themselves
The property of NaN objects not being equal to themselves is more harmful than helpful. We should probably draw the line at well-defined numeric contexts such as the decimal module and stop trying to propagate NaN awareness throughout the entire object model.
Raymond
-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20100324/a4983fe4/attachment.html>
- Previous message: [Python-Dev] Why is nan != nan?
- Next message: [Python-Dev] Why is nan != nan?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]