On Thu, Apr 28, 2011 at 12:53 AM, Guido van Rossum <gu...@python.org> wrote: >> What surprises me is that anyone gets surprised by anything when >> experimenting with an object that isn't equal to itself. It is roughly in >> the same category as creating a __hash__ that has no relationship to __eq__ >> or making self-referencing sets or setting False,True=1,0 in python 2. >> See http://bertrandmeyer.com/2010/02/06/reflexivity-and-other-pillars-of-civilization/ for >> a nice blog post on the subject. > > Maybe we should just call off the odd NaN comparison behavior?
Rereading Meyer's article (I read it last time this came up, but it's a nice piece, so I ended up going over it again this time) the quote that leapt out at me was this one: """A few of us who had to examine the issue recently think that — whatever the standard says at the machine level — a programming language should support the venerable properties that equality is reflexive and that assignment yields equality. Every programming language should decide this on its own; for Eiffel we think this should be the specification. Do you agree?""" Currently, Python tries to split the difference: "==" and "!=" follow IEEE754 for NaN, but most other operations involving builtin types rely on the assumption that equality is always reflexive (and IEEE754 be damned). What that means is that "correct" implementations of methods like __contains__, __eq__, __ne__, index() and count() on containers should be using "x is y or x == y" to enforce reflexivity, but most such code does not (e.g. our own collections.abc.Sequence implementation gets those of these that it implements wrong, and hence Sequence based containers will handle NaN in a way that differs from the builtin containers) And none of that is actually documented anywhere (other than a behavioural note in the 3.x documentation for PyObject_RichCompareBool), so it's currently just an implementation detail of CPython that most of the builtin containers behave that way in practice. Given the status quo, what would seem to be the path of least resistance is to: - articulate in the language specification which container special methods are expected to enforce reflexivity of equality (even for non-reflexive types) - articulate in the library specification which ordinary container methods enforce reflexivity of equality - fix any standard library containers that don't enforce reflexivity to do so where appropriate (e.g. collections.abc.Sequence) Types with a non-reflexive notion of equality still wouldn't play nicely with containers that didn't enforce reflexivity where appropriate, but bad interactions between 3rd party types isn't really something we can prevent. Backing away from having float and decimal.Decimal respect the IEEE754 notion of NaN inequality at this late stage of the game seems like one for the "too hard" basket. It also wouldn't achieve much, since we want the builtin containers to preserve their invariants even for 3rd party types with a non-reflexive notion of equality. Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com