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