PEP 218 Re: ANN: set-0.1 module available

Huaiyu Zhu huaiyu at gauss.almadan.ibm.com
Tue May 21 14:10:30 EDT 2002


Erik Max Francis <max at alcyone.com> wrote:
>Huaiyu Zhu wrote:
>
>> There need to be a different equal operator === (read as "always
>> equal")
>> that is used to compare keys.
>
>No doubt such a proposal immediately would doom a revised PEP to
>failure.

That's the main reason I've been thinking about this for two years without
saying much about it.  It is necessary.  It will not be accepted.  What a
pity.

>
>But that isn't the real issue.  The problem with hash/identity
>collisions within a set is not that defining some metaequality is
>problematic (which it is), it's that after the set has been created, a
>mutable object can have its value changed, potentially even to something
>that clashes with another object (mutable or not) in the same set.

As I said several times before (perhaps in a diverging thread), mutable
objects should only be compared by identity, not by value.  Therefore if
a===b, then their contents are guaranteed to be alwasy equal.  Mutable and
immutable objects are never "always equal":

a = {1,2}
b = {1,2} const
a === b  # false
a == b   # true
a.add(3)
print a  # {1,2,3}
a === b  # false
a == b   # false

That is, "==" only cares about an instant, but "===" cares for eternity.

>Python, as far as I know, does not have any facilities for some kind of
>implicit callback to containers that happens whenever an object changes
>state, and so this means that once you've already placed mutable objects
>in a set, they can change value willy nilly and completely break the
>invariant of the set (namely that no two contained objects are
>identical), essentially defeating the whole purpose for the set in the
>first place.

Does not matter.  If (a===b), they are refering to the same object.
Whatever their contents are change to, they are changed together.  If
not(a===b), then changing values of a and b will not result in (a===b), even
at times when (a==b).

This operator is very similar to "is", except that it is semantics-oriented
instead of implementation-oriented.  That is, there would not be "1 is 1"
but "101 is not 101" kind of stuff.

The main mental gymnastic needed is regarding "===" as the identity
operator, "==" only as the equality operator.  Two things can be equal at a
time but still not identical.  Thus in the the above example a and b are
indeed *not* identical, even at the time when their values are equal.

Another mental gymnastic needed is realizing that mutable sets, however
useful they are, are not mathematical sets.  The main difference being that
their identities are not defined by their contents.  The mathematical model
would be a time sequence of sets, which does not have much practical use
here, except to show that "{1,2} const" and "{1,2}" are two entirely
different beasts.

>This issue exists regardless of whether you come up with some concept of
>metaequality or not; it will be present as long as the set can contain
>mutable objects.

It does not depend on mutability per se, but rather on whether mutations
disturb identity.  The identity operator "===" is so defined that it is not
changed by mutations.

Huaiyu



More information about the Python-list mailing list