[Python-Dev] Re: Re: lists v. tuples

Thomas Wouters thomas@xs4all.net
Sun, 16 Mar 2003 20:42:00 +0100

On Sun, Mar 16, 2003 at 07:32:04AM -0500, Guido van Rossum wrote:

> > Guido> Yes.  And I'm still hoping to remove __cmp__; there should be
> > Guido> only one way to overload comparisons.

[ Andrew Koenig ]
> > Moreover, for some data structures, the __cmp__ approach can be
> > expensive.  For example, if you're comparing sequences of any kind,
> > and you know that the comparison is for == or !=, you have your answer
> > immediately if the sequences differ in length.  If you don't know
> > what's being tested, as you wouldn't inside __cmp__, you may spend a
> > lot more time to obtain a result that will be thrown away.

> Yes.  OTOH, as long as cmp() is in the language, these same situations
> are more efficiently done by a __cmp__ implementation than by calling
> __lt__ and then __eq__ or similar (it's hard to decide which order is
> best).  So cmp() should be removed at the same time as __cmp__.

I'm confused, as well as conflicted. I know I'm not well educated in
language design or mathematics, and I realize that comparisons between types
don't always make *mathematical* sense, but to go from there to removing
type-agnostic (not the right term, but bear with me) list-sorting and
three-way comparison altogether is really a big jump, and one I really don't
agree with. I find being able to sort (true) heterogeneous lists in a
consistent if not 'purely' sensible manner to be quit useful at times, and
all other times I already know I have a homogeneous list and don't care
about it. It's a practical approach because I don't have to think about how
it's going to be sorted, I don't have to take every edgecase into account,
and I don't have to know in advance what my list is going to contain (or
update all calls to 'sort' when I find I have to find a conflicting type to
the list.) I do not see how this is harmful; the cases I've seen where
people bump into this the hard way (e.g. doing "0" < 1) were fundamental
misunderstandings that would be corrected in a dozen other ways. Allowing
'senseless' comparisons does not strike me as a major source of confusion or
bad code.

I was uneasy about the change in complex number comparison, but I didn't
mind that, then, because it is a very rarely used feature to start with and
when looking at it from a 'unified number' point of view, it makes perfect
sense. But the latter does not apply to most other types, and I don't
believe it should. My defensive programming nature (I write Perl for a
living, if I wasn't defensive by nature I'd have committed suicide by now)
would probably make me always use a 'useful sorter' function, possibly by
using subclasses of list (so I could guard against other subtle changes,
too, by changing one utility library, tw.Tools. Yuck.) I really don't like
how that affects the readability of the code. I'd feel better about
disallowing '==' for floating point numbers, as I can see why that is a
problem. But I don't feel good about that either ;)

I really like how most Python objects are convenient. Lists grow when you
need them to, slices do what you think they do, dicts can take any
(hashable) object as a key (boy, do I miss that in Perl), mathematical
operations work with simple operators even between types, objects,
instances, classes and modules all behave consistently and have consistent
syntax. Yes, Python has some odd quirks, some of which require a comment or
two when writing code that will be read by people with little or no Python
knowledge (e.g. my colleagues.) But I believe adding a small comment like
"'global' is necessary to *assign* to variables in the module namespace" or
"'%(var)s' is how we say '$var'" or "'x and y or s' is like 'x ? y : s' if y
is true, which it always is here" or any of the half-dozen other things I
can imagine, not counting oddities in standard modules, is preferable over
forcing the syntax or restricting the usage to try and 'solve' the quirks.

> And then we should also change list.sort(), as Tim points out.  Maybe
> we can start introducing this earlier by using keyword arguments:

>   list.sort(lt=function)     sorts using a < implementation
>   list.sort(cmp=function)    sorts using a __cmp__ implementation

Perhaps we need stricter prototypes, that define the returnvalue. Or
properties on (or classes of) functions, so we can tell whether a function
implements the lessthan interface, or the threeway one. It would definately
*look* better than the above ;)

Practically-beats-this-idea-in-my-eyes'ly y'rs ;)
Thomas Wouters <thomas@xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!