[Python-Dev] PyObject_RichCompareBool identity shortcut

Nick Coghlan ncoghlan at gmail.com
Thu Apr 28 09:57:59 CEST 2011


On Thu, Apr 28, 2011 at 5:30 PM, Alexander Belopolsky
<alexander.belopolsky at gmail.com> wrote:
> On Thu, Apr 28, 2011 at 2:54 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> ..
>> No, as Raymond has articulated a number of times over the years, it's
>> a property of the equivalence relation that is needed in order to
>> present sane invariants to users of the container. I included in the
>> bug report the critical invariants I am currently aware of that should
>> hold, even when the container may hold types with a non-reflexive
>> definition of equality:
>>
>>  assert [x] == [x]                     # Generalised to all container types
>>  assert not [x] != [x]                # Generalised to all container types
>>  for x in c:
>>    assert x in c
>>    assert c.count(x) > 0                   # If applicable
>>    assert 0 <= c.index(x) < len(c)      # If applicable
>>
>
> It is an interesting question of what "sane invariants" are.  Why you
> consider the invariants that you listed essential while say
>
> if c1 == c2:
>   assert all(x == y for x,y in zip(c1, c2))
>
> optional?

Because this assertion is an assertion about the behaviour of
comparisons that violates IEEE754, while the assertions I list are all
assertions about the behaviour of containers that can be made true
*regardless* of IEEE754 by checking identity explicitly.

The correct assertion under Python's current container semantics is:

  if list(c1) == list(c2):  # Make ordering assumption explicit
    assert all(x is y or x == y for x,y in zip(c1, c2))  # Enforce reflexivity

Meyer is a purist - sticking with the mathematical definition of
equality is the sort of thing that fits his view of the world and what
Eiffel should be, even if it hinders interoperability with other
languages and tools. Python tends to be a bit more pragmatic about
things, in particular when it comes to interoperability, so it makes
sense to follow IEEE754 and the decimal specification at the
individual comparison level.

However, we can contain the damage to some degree by specifying that
containers should enforce reflexivity where they need it. This is
already the case at the implementation level (collections.Sequence
aside), it just needs to be pushed up to the language definition
level.

> Can you give examples of algorithms that would break if one of your
> invariants is violated, but would still work if the data contains
> NaNs?

Sure, anything that cares more about objects than it does about
values. The invariants are about making containers behave like
containers as far as possible, even in the face of recalcitrant types
like IEEE754 floating point.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list