[Python-3000] Need closure on __cmp__ removal

Guido van Rossum guido at python.org
Tue Jan 8 23:41:33 CET 2008


list.sort() and built-in sorted() are the least of our problems: even
though the API uses cmp, the implementation actually only ever uses
'<'; and the preferred API is to use the 'key' argument instead of
passing a compare function; that's much more efficient.

Maybe we should retire the compare function completely in 3.0?

On Jan 8, 2008 2:34 PM, hashcollision <hashcollision at gmail.com> wrote:
> Ok, I do see your point, but how would one pass in a custom comparison
> function to sorted?
>
>
>
>
> On Jan 7, 2008 11:55 PM, Guido van Rossum <guido at python.org> wrote:
>
> >
> >
> >
> > On Jan 7, 2008 8:48 PM, hashcollision <hashcollision at gmail.com> wrote:
> > >
> > >
> > > > But the biggest thing missing is precise semantics. Saying "exactly
> > > > the same semantics as with Python 2.5" doesn't cut it (those semantics
> > > > are incredibly hairy and sometimes surprising, and their
> > > > implementation was a nightmare -- I've rarely been as relieved as when
> > > > I was able to cut those out of the implementation).
> > >
> > >
> > > Why is that so? I might be being naive, but what is wrong with something
> > > like this:
> > >
> > > def cmp(a, b):
> > >     if hasattr(a, '__cmp__'):
> > >         return a.__cmp__(b)
> > >     elif hasattr(b, '__cmp__'):
> > >         return -1 * b.__cmp__(a)
> > >     elif hasattr(a, '__le__') and hasattr(a, '__ge__'):
> > >         x = a <= b
> > >         y = a >= b
> > >         if x and y:
> > >             return 0
> > >         elif x:
> > >             return -1
> > >         elif y:
> > >             return 1
> > >     elif hasattr(b, '__le__') and hasattr(b, '__ge__'):
> > >         x = b <= a
> > >         y = b >= a
> > >         if x and y:
> > >             return 0
> > >         elif x:
> > >             return 1
> > >         elif y:
> > >             return -1
> > >     elif hasattr(a, '__eq__'):
> > >         if a == b:
> > >             return 0
> > >         if hasattr(a, '__lt__'):
> > >             if a < b:
> > >                 return -1
> > >             else:
> > >                 return 1
> > >         elif hasattr(a, '__gt__'):
> > >             if a > b:
> > >                 return 1
> > >             else:
> > >                 return -1
> > >         else:
> > >             raise NotImplemented()
> > >     elif hasattr(b, '__eq__'):
> > >         if a == b:
> > >             return 0
> > >         if hasattr(b, '__lt__'):
> > >             if b < a:
> > >                 return 1
> > >             else:
> > >                 return -1
> > >         elif hasattr(b, '__gt__'):
> > >              if b > a:
> > >                 return -1
> > >             else:
> > >                 return 1
> > >         else:
> > >             raise NotImplemented()
> > >     else:
> > >         raise NotImplemented()
> >
> > You don't call that hairy? :-)
> >
> > Anyway, one of the additional complications is that it is supposed to
> > be implemented in C, and there is one C slot for all six comparisons
> > together (which of the six is an argument). The 2.x rules are also
> > further complicated in that sometimes the RHS is tried before the LHS
> > (in case the RHS is an instance of a subclass of the class of the
> > LHS).
> >
> > And I think you've ignored the possibility that a.__cmp__(b) might
> > return NotImplemented.
> >
> > Just believe me, it's hairy.
> >
> >
> >
> >
> > --
> > --Guido van Rossum (home page: http://www.python.org/~guido/)
> >
>
>



-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-3000 mailing list