Would there be support for a more general cmp/__cmp__

Antoon Pardon apardon at forel.vub.ac.be
Wed Oct 26 09:36:47 CEST 2005


Op 2005-10-25, Christopher Subich schreef <csubich.spam.block at spam.subich.block.com>:
> Antoon Pardon wrote:
>> Op 2005-10-25, Christopher Subich schreef <csubich.spam.block at spam.subich.block.com>:
>> 
>
>>>Which is exactly why a < b on sets returns True xor False, but cmp(a,b) 
>>>throws an exception.
>> 
>> 
>> I don't see the conection.
>> 
>> The documentation states that cmp(a,b) will return a negative value if
>> a < b. So why should it throw an exception?
>
> Because it's useful that cmp(a1, a2) should either (return a value) or 
> (throw an exception) for any element a1, a2 within type(a1) cross 
> type(a2).  If cmp sometimes is okay and sometimes throws an exception, 
> then it leads to weird borkage in things like trees.

Oh no, not "we have to protect the programmer" argument again.

This kind of behaviour will manifest itself soon enough in testing.
Almost eacht time some addition is suggested that could help
with finding bugs, it gets rejected that because such bugs will be
found soon enough with proper testing.

And in order to protect one specific case, you limit programmers
the use in all other cases where it could be usefull.

> With that in mind, not all sets are comparable.  {a} and {b} have no 
> comparison relationship, as you've pointed out, aside from not-equal. 
> I'll get to why "not-equal" is a bad idea below.
>
>>>cmp(a,b) asks for their relative rankings in some total ordering.
>> 
>> 
>> The documentation doesn't state that. I also didn't find anything in
>> the documentation on how the programmer should code in order to
>> enforce this.
>
> Most programmers are simply programmers; they haven't had the benefit of 
> a couple years' pure-math education, so the distinction between "partial 
> order" and "total order" is esoteric at best.

So. these people are not familiar with higher order functions either.
Do you think we should make python a language only for the not too
educated. 

> With that in mind, compare should conform, as best as possible, to 
> "intuitive" behavior of comparison.  Since comparisons are mostly done 
> on numbers, an extension of comparisons should behave "as much like 
> numbers" as possible.

IMO cmp(set([0]), set([0,1])) giving a result of -1, is much more
number like behaviour than throwing an exception. With numbers
we have that a < b implies cmp(a,b) < 0. So the most number like
behaviour for sets would also be that a < b would imply cmp(a,b) < 0.

>> Maybe the original idea was that cmp provided some total ordering,
>> maybe the general idea is that cmp should provide a total ordering,
>> but that is not documented, nor is there any documentation in
>> helping the programmer in this. 
>
> I doubt that anyone was thinking about it in such depth.  My bet is that 
> the thought process goes this way:

Which seems to be my biggest frustration with python. Things are
often enough not thought out in depth.

>>>>>from decimal import Decimal
>>>>>Zero = Decimal(0)
>>>>>cmp( ( ) , Zero)
>> 
>> -1
>> 
>>>>>cmp(Zero, 1)
>> 
>> -1
>> 
>>>>>cmp(1, ( ) )
>> 
>> -1
>
> I'd argue that the wart here is that cmp doesn't throw an exception, not 
> that it returns inconsistent results.  This is a classic case of 
> incomparable objects, and saying that 1 < an empty tuple is bordering on 
> meaningless.

I wont argue with you here, but it is what python gives as now.
Changing this behaviour is not going to happen.

>>>For a 
>>>space that does not have a total ordering, cmp(a,b) is meaningless at 
>>>best and dangerous at worst.
>> 
>> 
>> The current specs and implemantation are.
>> 
>> I see nothing wrong with a function that would provide four kinds of
>> results when given two elements. The same results as cmp gives now
>> when it applies and None or other appropiate value or a raised
>> exception when not.
>> 
>> Given how little this functionality differs from the current cmp,
>> I don't see why it couldn't replace the current cmp.
>
> My biggest complaint here is about returning None or IncomparableValue; 
> if that happens, then all code that relies on cmp returning a numeric 
> result will have to be rewritten.

I don't know. There are two possibilities.

1) The user is working with a total order. In that case the None
or IncomparableValues won't be returned anyway so nothing about
his code has to change.

2) The user is working with a partial order. In that case cmp
doesn't provide consistent results so the use of cmp in this
case was a bug anyway.

> Comparing incomparables is an exceptional case, and hence it should 
> raise an exception.
>
> As for saying that cmp should return some times and raise an exception 
> other times, I just find it squicky.

But cmp already behaves this way. The only difference would be that
the decision would be made based on the values of the objects instead
of only their class.

> Admittedly, this is entirely up to 
> the class designer, and your proposed guideline wouldn't change cmp's 
> behavior for clases that /are/ totally ordered.
>
> Then again, sets excepted, your guideline doesn't seem very applicable 
> in standard library code.

Well AFAIAC this isn't specific about library code.

-- 
Antoon Pardon



More information about the Python-list mailing list