Guido, Here are my comments on PEP 207. (I've also gone back and read most of the 1998 discussion. What a tedious, in terms of time, but enlightening, in terms of content, discussion that was.) | - New function: | | PyObject *PyObject_RichCompare(PyObject *, PyObject *, enum cmp_op) | | This performs the requested rich comparison, returning a Python | object or raising an exception. The 3rd argument must be one of | LT, LE, EQ, NE, GT or GE. I'd much prefer '<', '<=', '=', etc. to LT, LE, EQ, etc. | Classes | | - Classes can define new special methods __lt__, __le__, __gt__, | __ge__, __eq__, __ne__ to override the corresponding operators. | (You gotta love the Fortran heritage.) If a class overrides | __cmp__ as well, it is only used by PyObject_Compare(). Likewise, I'd prefer __less__, __lessequal__, __equal__, etc. to __lt__, __le__, __eq__, etc. I'm not keen on the FORTRAN derived symbolism. I also find it contrary to Python's heritage of being clear and concise. I don't mind typing __lessequal__ (or __less_equal__) once per class for the additional clarity. | - Should we even bother upgrading the existing types? Isn't this question partly related to the coercion issue and which type of comparison takes precedence? And if so, then I would think the answer would be 'yes'. Or better still see below my suggestion of adding poor and rich comparison operators along with matrix-type operators. - If so, how should comparisons on container types be defined? Suppose we have a list whose items define rich comparisons. How should the itemwise comparisons be done? For example: def __lt__(a, b): # a<b for lists for i in range(min(len(a), len(b))): ai, bi = a[i], b[i] if ai < bi: return 1 if ai == bi: continue if ai > bi: return 0 raise TypeError, "incomparable item types" return len(a) < len(b) This uses the same sequence of comparisons as cmp(), so it may as well use cmp() instead: def __lt__(a, b): # a<b for lists for i in range(min(len(a), len(b))): c = cmp(a[i], b[i]) if c < 0: return 1 if c == 0: continue if c > 0: return 0 assert 0 # unreachable return len(a) < len(b) And now there's not really a reason to change lists to rich comparisons. I don't understand this example. If a[i] and b[i] define rich comparisons, then 'a[i] < b[i]' is likely to return a non-boolean value. Yet the 'if' statement expects a boolean value. I don't see how the above example will work. This example also makes me think that the proposals for new operators (ie. PEP 211 and 225) are a good idea. The discussion of rich comparisons in 1998 also lends some support to this. I can see many uses for two types of comparison operators (as well as the proposed matrix-type operators), one set for poor or boolean comparisons and one for rich or non-boolean comparisons. For example, numeric arrays can define both. Rich comparison operators would return an array of boolean values, while poor comparison operators return a boolean value by performing an implied 'and.reduce' operation. These operators provide clarity and conciseness, without much change to current Python behavior. -- Paul
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4