<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Mar 24, 2010, at 2:31 PM, Alexander Belopolsky wrote:</div><br><blockquote type="cite"><div>"""<br>In this context it doesn't particularly shock me that operations on<br>NaN should cause invariant violations. After all, isn't NaN supposed<br>to mean "not a number"? If it's not a number, it doesn't have to<br>satisfy the properties of numbers.<br>"""<br></div></blockquote><div><br></div><div><div>This sound like a good, universal reply to "bug reports" about</div><div>various containers/tools not working with NaNs :-)</div><div><br></div><div>Bug report: "Container X or Function Y doesn't behave well when I</div><div>give it a NaN as an input".</div><div><br></div><div>Closed -- Won't fix: "It does not shock me that a NaN violates that</div><div>tool or container's invariants."</div></div><div><br></div><blockquote type="cite"><div><br>To bring the discussion back on topic for python-dev, I would argue<br>that reflexivity should hold for hashable values. Having it otherwise<br>would lead to unsurmountable problems when storing such values in sets<br>or using them as keys in dictionaries. If x == x is False stays for x<br>= float('nan'), I would argue that hash(float('nan')) should raise<br>NotImplemented or ValueError.</div></blockquote><br></div><div>Hashability isn't the only place where you have a problem.</div><div>Even unordered collections are affected:</div><div><br></div><div> >>> class ListBasedSet(collections.Set):</div><div> ''' Alternate set implementation favoring space over speed</div><div> and not requiring the set elements to be hashable. '''</div><div> def __init__(self, iterable):</div><div> self.elements = lst = []</div><div> for value in iterable:</div><div> if value not in lst:</div><div> lst.append(value)</div><div> def __iter__(self):</div><div> return iter(self.elements)</div><div> def __contains__(self, value):</div><div> return any(value == elem for elem in self.elements)</div><div> def __len__(self):</div><div> return len(self.elements)</div><div><br></div><div> </div><div>>>> n = float('Nan')</div><div>>>> s = ListBasedSet([n])</div><div>>>> n in s # unexpected result</div><div>False</div><div><div>>>> len(s) # expected result</div><div>1</div></div><div>>>> len(s & s) # unexpected result</div><div>0</div><br><div>If we want to be able to reason about our programs,</div><div>then we need to rely on equality relations being</div><div>reflexsive, symmetric, and transitive. Otherwise,</div><div>containers and functions can't even make minimal </div><div>guarantees about what they do.</div><div><br></div><div>Anything else smells of a Douglas Hofstadter style</div><div>or Betrand Russell style logic bomb:</div><div><br></div><div>* this sentence is a lie</div><div>* this object isn't equal to itself</div><div>* this is <span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px; ">a set containing sets that are not members of themselves</span></div><div><font class="Apple-style-span" face="sans-serif" size="3"><span class="Apple-style-span" style="font-size: 13px; line-height: 19px;"><i><br></i></span></font></div><div><font class="Apple-style-span" face="sans-serif" size="3"><span class="Apple-style-span" style="font-size: 13px; line-height: 19px;">The property of NaN objects not being equal to themselves</span></font></div><div><font class="Apple-style-span" face="sans-serif" size="3"><span class="Apple-style-span" style="font-size: 13px; line-height: 19px;">is more harmful than helpful. We should probably draw the</span></font></div><div><font class="Apple-style-span" face="sans-serif" size="3"><span class="Apple-style-span" style="font-size: 13px; line-height: 19px;">line at well-defined numeric contexts such as the decimal module</span></font></div><div><font class="Apple-style-span" face="sans-serif" size="3"><span class="Apple-style-span" style="font-size: 13px; line-height: 19px;">and stop trying to propagate NaN awareness throughout the</span></font></div><div><font class="Apple-style-span" face="sans-serif" size="3"><span class="Apple-style-span" style="font-size: 13px; line-height: 19px;">entire object model.</span></font></div><div><font class="Apple-style-span" face="sans-serif" size="3"><span class="Apple-style-span" style="font-size: 13px; line-height: 19px;"><br></span></font></div><div><font class="Apple-style-span" face="sans-serif" size="3"><span class="Apple-style-span" style="font-size: 13px; line-height: 19px;"><br></span></font></div><div><font class="Apple-style-span" face="sans-serif" size="3"><span class="Apple-style-span" style="font-size: 13px; line-height: 19px;">Raymond</span></font></div><div><br></div></body></html>