[Python-3000] Please re-add __cmp__ to python 3000

Adam Olsen rhamph at gmail.com
Mon Oct 29 20:49:53 CET 2007


On 10/29/07, David A. Wheeler <dwheeler at dwheeler.com> wrote:
> I think several postings have explained better than I have on why __cmp__ is still very valuable.  (See below.)
>
> Guido van Rossum posted earlier that he was willing to entertain a PEP to restore __cmp__, so I've attempted to create a draft PEP, posted here:
>   http://www.dwheeler.com/misc/pep-cmp.txt
> Please let me know if it makes sense.  Thanks.
>
> Greg Ewing stated "Why not provide a __richcmp__ method that directly connects
> with the corresponding type slot? All the comparisons eventually end up there anyway, so it seems like the right place to provide a one-stop comparison method in the 3.0 age."
> It _seems_ to me that this is the same as "__cmp__", and if so, let's just keep using the same name (there's nothing wrong with the name!).  But maybe I just don't understand the comment, so explanation welcome.

I believe the intent was for __richcmp__ to take an argument
indicating what sort of comparison is to be done (as tp_richcompare
does in C.)  ie, you'd write code like this:

    def __richcmp__(self, other, op):
        if !isinstance(other, MyType):
            return NotImplemented
        return richcmp(self.foo, other.foo, op)

Short-circuiting of equality checks (due to identity or interning)
would work right.  Likewise, there's no odd behaviour with
comparable-but-unorderable types.

It's not clear to me how many distinct operations you'd need though,
or how acceptable reflections would be.  Would only two operations,
equality and ordering, be sufficient?  Just what are the non-symmetric
use cases the current design caters to?


>
>
>
> --- David A. Wheeler
>
> ========================================
>
> Aahz:
> >From my perspective, the real use case for cmp() is when you want to do
> >a three-way comparison of a "large" object (for example, a Decimal
> >instance). You can store the result of cmp() and then do a separate
> >three-way branch.
>
> and reply to the note "I'm having troubles coming up with things where
> the *basic* operator is really a cmp-like function.", there were two replies..
>
>
> Guido van Rossum:
> >Here's one. When implementing the '<' operator on lists or tuples, you
> > really want to call the 'cmp' operator on the individual items,
> > because otherwise (if all you have is == and <) the algorithm becomes
> > something like "compare for equality until you've found the first pair
> > of items that are unequal; then compare those items again using < to
> > decide the final outcome". If you don't believe this, try to implement
> > this operation using only == or < without comparing any two items more
> > than once.
>
> and
>
> Greg Ewing:
> > Think of things like comparing a tuple. You need to work your
> > way along and recursively compare the elements. The decision
> > about when to stop always involves ==, whatever comparison
> > you're trying to do. So if e.g. you're doing <, then you have
> > to test each element first for <, and if that's false, test
> > it for ==. If the element is itself a tuple, it's doing this
> > on its elements too, etc., and things get very inefficient.
> >
> > If you have a single cmp operation that you can apply to the
> > elements, you only need to do it once for each element and it
> > gives you all the information you need.
>
> _______________________________________________
> Python-3000 mailing list
> Python-3000 at python.org
> http://mail.python.org/mailman/listinfo/python-3000
> Unsubscribe: http://mail.python.org/mailman/options/python-3000/rhamph%40gmail.com
>


-- 
Adam Olsen, aka Rhamphoryncus


More information about the Python-3000 mailing list