
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!