A
Adam Skutt
The fact that you think that that's "differing behaviour" is what makes
it a misfeature. The fact that you think that '==' can take objects as
operands confirms that Java *does* confuse programmers.
The equality operator can absolutely be used between two objects. Try
it if you don't believe me. It always does identity comparison when
given two objects. It can also be given two primitives, and in this
case, it does value comparison. Despite performing different
operations with the same symbol, there's little risk of confusion
because I can trivially figure out if a variable is an object or an
primitive.
They're not "disjoint", in fact one almost always implies the other (*).
"Almost always" isn't a rebuttal. There's no requirement whatsoever
for the results of identity comparison to be related to the results of
value comparison, ergo they are disjoint. Changing one doesn't have
to influence the other. Please note that I never advocated doing what
Java does, I merely noted what it does.
Python's idea is that, by default, any object is equal to itself and
only itself.
Which is just wrong-headed. Many types have no meaningful definition
for value equality, ergo any code that attempts to perform the
operation is incorrect.
(*) nan == nan is false, but, at least conceptually, a 'NotComparable'
exception should be raised instead. That wouldn't be very useful, though.
There shouldn't be, to be fair.
Which is the whole problem. It's nice to keep erroneous conditions
out of your domain, but it's just not always possible. I don't know
how you implement NaN (which you need) without allowing for this. I
don't know how you implement SQL NULL without allowing for this.
While lots of problems can avoid this issue, I'm not sure all problems
can. Moreover, I don't know how to implement a value comparison for
many objects, so the operation should just be undefined.
I should point out that I was a little hasty in painting Python with
the same brush as C# and excluding Java. Python and Java are equally
bad: value equality defaults to identity equality but there are
distinct operations for telling them apart. People want identity
equality in Python write 'is', not '=='. People who explicitly want
value equality in Java write 'equals()'. I apologize, and blame
skipping breakfast this morning.
C# is arguably worse, since '==' on objects is defined as identity
equality unless it has been overridden. This means that that the
intent of the operation varies with no easy way to figure it out in
context, you simply have to know. C# also provides a way to test only
for identity, Object.ReferenceEquals(), but it's underused.
Ultimately this is really a problem of documentation: the language
shouldn't encourage conflation of intent in the manner it does.
I can agree on that, but that's something you can solve with a minor
modification to the language. What I was talking about is the core
design of Java and Python.
The only difference is I see is which comparison is performed by the
== symbol. But I don't see how nor why Python's decisions are
superior to Java. Plus, I never suggested that Python should do what
Java does, merely noted what it did since it seemed relevant to the
discussion.
Adam