D
Dan Sommers
Dan said:Rocco Moretti wrote:
The main problem is that Python is trying to stick at least three
different concepts onto the same set of operators: equivalence (are
these two objects the same?), ordering (in a sorted list, which comes
first?), and mathematical "size".Python inherits that wackiness directly from (often wacky) world ofThis gives the wacky world where
"[(1,2), (3,4)].sort()" works, whereas "[1+2j, 3+4j].sort()" doesn't.
Mathematics.
IMO, the true wackiness is that
[ AssertionError, (vars, unicode), __name__, apply ].sort( )
"works," too. Python refusing to sort my list of complex numbers is a
Good Thing.
The "wackyness" I refered to wasn't that a list of complex numbers isn't
sortable, but the inconsistent behaviour of list sorting. As you
mentioned, an arbitraty collection of objects in a list is sortable, but
as soon as you throw a complex number in there, you get an exception.
Yes, I agree: it is inconsistent.
One way to handle that is to refuse to sort anything that doesn't have
a "natural" order. But as I understand it, Guido decided that being
able to sort arbitrary lists is a feature, not a bug. But you can't
sort ones with complex numbers in them, because you also want
'1+3j<3+1j' to raise an error.
As George Sakkis noted, Guido has since recanted. Unfortunately, in
this case, the time machine would have broken too much existing code.
What "conflict"? Where are you getting the doesn't/can't/shouldn't
prescription from?
Perhaps "conflict" wasn't quite the right word. For example, if I
define __ne__ and __equal__ and __lt__, then which method(s) should
Python use if I later use a <= or a >= operator?
"Doesn't" and "can't" (call me pessimistic) comes from all the issues
and disagreements we're having in this thread, and "shouldn't" comes
from the Zen:
Explicit is better than implicit.
In the face of ambiguity, refuse the temptation to guess.
Which method you use depends on what you want to achieve:
(Hypothetical Scheme)
Object Identity? - use 'is'
Mathematical Ordering? - use '__eq__' & friends
Object Equivalence? - use '__equiv__'
Arbitrary Ordering? (e.g. for list sorting) - use '__order__'
So which method would python use when sorting a list that happens to
consist only of numbers? or a list that contains mostly integers and a
few complex numbers?
The only caveat is to define sensible defaults for the cases where one
fuction is not defined. But that shouldn't be too hard.
At the risk of repeating myself:
Explicit is better than implicit.
In the face of ambiguity, refuse the temptation to guess.
Also, as I noted in a previous discussion on an unrelated topic, it
seems that we all have our own notions and limitations of expliciticity
and impliciticity.
__eqiv__ -> __eq__ -> is
__order__ -> __lt__/__cmp__
Except if you want the situation where "[1+2j, 3+4j].sort()" works, and
'1+3j < 3+1j' fails.
I'm sticking with my position that both should fail, unless you
*explicity* tell sort what to do (since for now, we all seem to agree
that the other one should fail). If I have an application that thinks
it has to sort a list of arbitrary objects, then I have to be clever
enough to help.
I think the issue is you thinking along the lines of Mathematical
numbers, where the four different comparisons colapse to one. Object
identity? There is only one 'two' - heck, in pure mathematics, there
isn't even a 'float two'/'int two' difference. Equivalence *is*
mathematical equality, and the "arbitrary ordering" is easily defined
as "true" ordering. It's only when you break away from mathematics do
you see the divergance in behavior.
IIRC, there was a discussion about overhauling of all of Python's
numbers to make them act more like the mathematical entities that they
represent rather than the Python objects that they are. The long/int
"consolidation," better handling of integer division, and the Decimal
class came out of that discussion. But that still leaves the issue of
what to do with 1 < "foo" and "bar" > 2j and 3j < 4j.
Regards,
Dan