Mike said:
This isn't "easy". It's an ugly hack you have to use everytime you
want to iterate through a heterogenous set doing equality tests.
I wouldn't define this as an "ugly hack". These are four simple line,
which state clearly and precisely what you mean, and always work. I have
seen ugly hacks in my life, and they don't look like this.
You're replacing "false" with an "emphathetic false", that *all*
containers to change for the worse to deal with it.
I don't see how they change for the worse if they have exactly the same
functionality and a few added lines of implementation.
Except that we now need four versions of internal data structures,
instead of two: list, tuple, idlist, idtuple; set, idset, frozenset,
frozenidset, and so on. What's wrong with this is that it's ugly.
Again, "ugly" is a personal definition. I may call this "explicitness".
By the way, what's the "and so on" - I think that these are the only
built-in containers.
Yes you can, and it's even easy. All you have to do is use custom
classes that raise an exception if they don't
You can't create a general container with my proposed == behaviour.
That's what I meant.
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. Another example - you can't search for a
specific list object in another list.
Note that this behavior also has the *highly* pecular behavior that a
doesn't necessarily equal a by default.
Again, "peculiar" is your aesthethic sense. I would like to hear
objections based on use cases that are objectively made more difficult.
Anyway, I don't see why someone should even try checking if "a==a", and
if someone does, the exception can say "this type doesn't support value
comparison. Use the "is" operator".
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).
* 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.
* It is more forward compatible - when it is discovered that two types
can sensibly be compared, the comparison can be defined, without
changing an existing behaviour which doesn't raise an exception.
The third example applies to the Decimal==float use case, and for every
type that currently has the default identity-based comparison and that
may benefit from a value-based comparison. Take the class
class Circle(object):
def __init__(self, center, radius):
self.center = center
self.radius = radius
Currently, it's equal only to itself. You may decide to define an
equality operator which checks whether both the center and the radius
are the same, but since you already have a default equality operator,
that change would break backwards-compatibility.
Noam