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

Reply via email to