Why keep identity-based equality comparison?

Mike Meyer mwm at mired.org
Sun Jan 15 04:44:55 CET 2006


Noam Raphael <spam.noam at gmail.com> writes:
> Mike Meyer wrote:
>> Noam Raphael <spam.noam at gmail.com> writes:
>>>>>Also note that using the current behaviour, you can't easily
>>>>>treat objects that do define a meaningful value comparison, by
>>>>>identity.
>>>>Yes you can. Just use the "is" operator.
>>>Sorry, I wasn't clear enough. In "treating" I meant how containers
>>>treat the objects they contain. For example, you can't easily map a
>>>value to a specific instance of a list - dict only lets you map a
>>>value to a specific *value* of a list.
>> Wrong. All you have to do is create a list type that uses identity
>> instead of value for equality testing. This is easier than mapping an
>> exception to false.
> You're suggesting a workaround, which requires me to subclass
> everything that I want to lookup by identity (and don't think it's
> simple - I will have to wrap a lot of methods that return a list to
> return a list with a modified == operator).

No, I'm suggesting a general solution that works for *every* case
where you want something other than the standard equality case.

> I'm suggesting the use of another container class: iddict instead of
> dict. That's all.

You're suggesting adding a new builtin type to the language that deals
with one special case. Is this special case really that common? I
don't recall seeing anyone else ask for it in the last 10 years or so.

> I don't think that mapping an exception to false is so hard (certainly
> simpler than subclassing a list in that way), and the average user
> won't have to do it, anyway - it's the list implementation that will
> do it.

I disagree with both your assessments. Subclassing is trivial. And
every user who wants to compare elements in a container that might
include heterogenous types has to deal with this issue. That's more
than just lists, even if you only pay atttention to builtin
types. Nuts - you have to deal with it when you're adding elements to
a dictionary.

>>>Another example - you can't
>>>search for a specific list object in another list.
>> Your proposed == behavior doesn't change that at all.
> It does - *use idlist*.

You're mixing two proposals into the same thread. You'll forgive me
for referring to the original proposal.

>>>>I will point out why your example usages aren't really usefull if
>>>>you'll repeat your post with newlines.
>>>
>>>Here they are:
>>>* Things like "Decimal(3.0) == 3.0" will make more sense (raise an
>>>exception which explains that decimals should not be compared to
>>>floats, instead of returning False).
>> While I agree that Decimal(3.0) == 3.0 returning false doesn't make
>> sense, having it raise an exception doesn't make any more sense. This
>> should be fixed, but changing == doesn't fix it.
> No, it can't be fixed your way. It was decided on purpose that Decimal
> shouldn't be comparable to float, to prevent precision errors. I'm
> saying that raising an exception will make it clearer.

So how come I can compare decimals to floats?

>>> type(d)
<class 'decimal.Decimal'>
>>> d < 2.0
True
>>> d > 0.0
False

Are you proposing we should break this, which currently functions
correctly?

You're correct that this can't be fixed by "fixing" decimal alone. It
requires more work than that. It may not be possible to fix this
properly before Py3K. But your proposal can't be done until then
anyway. I've already started the process of proposing a proper fix.

>>>* You won't be able to use objects as keys, expecting them to be
>>>compared by value, and causing a bug when they don't. I recently wrote
>>>a sort-of OCR program, which contains a mapping from a numarray array
>>>of bits to a character (the array is the pixel-image of the char).
>>>Everything seemed to work, but the program didn't recognize any
>>>characters. I discovered that the reason was that arrays are hashed
>>>according to their identity, which is a thing I had to guess. If
>>>default == operator were not defined, I would simply get a TypeError
>>>immediately.
>> This isn't a use case. You don't get correct code with either version
>> of '=='. While there is some merit to doing things that make errors
>> easier to find, Python in general rejects the idea of adding
>> boilerplate to do so. Your proposal would generate lots of boilerplate
>> for many practical situations.
> I would say that there's a lot of merit to doing things that make
> errors easier to find. That's what exceptions are for.

Exceptions are for finding *programming errors*? That's a rather
unusual view of exceptions. 

> Please say what those practical situations are - that what I want.
> (I understand. You think that added containers and a try...except  fro
> time to time aren't worth it. I think they are. Do you have any other
> practical situations?)

That try...except is the boilerplate I'm talking about.

> You are right that I'm suggesting a try...except when testing if a
> list contains an object, but a case when you have a list with floats
> and Decimals, and you rely on "Decimal("3.0") in list1" to find only
> Decimals seems to me a little bit far-fetched. If you have another
> example, please say it.

But you're suggesting changing *far more* than just decimals, and have
made multiple suggestions. Exactly what are you looking for an example
of?

        <mike
-- 
Mike Meyer <mwm at mired.org>			http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.



More information about the Python-list mailing list