<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2014-09-22 17:51 GMT+02:00 David T. Lewis <span dir="ltr">&lt;<a href="mailto:lewis@mail.msen.com" target="_blank">lewis@mail.msen.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">We need positive confirmation that the code derived from that public<br>
repository was licensed MIT, or a statement from the original author that<br>
is now being released under MIT. I&#39;m sure that the original author will be<br>
happy to do that, but we do need a clear statement of license before we<br>
can allow the code to be added to trunk.<br>
<br>
Dave<br>
<div><div><br></div></div></blockquote><div><br></div><div>Sorry  for the late reply.<br></div><div>I mistakenly assumed the license problem was solved, but after verification, there is no mention of a license on the blog nor on the cincom public store repository.<br></div><div>I have sent private e-mail to Travis 2 days ago, but haven&#39;t received an answer yet.<br></div><div>I don&#39;t know him personnally, so I would welcome any one having a more direct channel to contact him.<br></div><div>Without a clear answer we&#39;ll have to retract these commits.<br></div><div>Unless you prefer a preventive retractation right now?<br><br></div><div>Nicolas<br></div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>
&gt; It was ported from a &quot;public repository&quot; into trunk.  Everything<br>
&gt; posted to trunk is MIT.<br>
&gt;<br>
&gt;<br>
&gt; On Mon, Sep 22, 2014 at 3:26 AM, Frank Shearar &lt;<a href="mailto:frank.shearar@gmail.com" target="_blank">frank.shearar@gmail.com</a>&gt;<br>
&gt; wrote:<br>
&gt;&gt; Yes, it looks very very nice.<br>
&gt;&gt;<br>
&gt;&gt; What&#39;s its licence again?<br>
&gt;&gt;<br>
&gt;&gt; frank<br>
&gt;&gt;<br>
&gt;&gt; On 21 September 2014 22:46, Chris Muller &lt;<a href="mailto:asqueaker@gmail.com" target="_blank">asqueaker@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt; What a *gorgeous* solution to multi-level sorting!  I love this!!<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Now I need to update some of my images to latest trunk just so I can<br>
&gt;&gt;&gt; get this..<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; On Fri, Sep 19, 2014 at 3:24 PM,  &lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>&gt; wrote:<br>
&gt;&gt;&gt;&gt; Nicolas Cellier uploaded a new version of Collections to project The<br>
&gt;&gt;&gt;&gt; Trunk:<br>
&gt;&gt;&gt;&gt; <a href="http://source.squeak.org/trunk/Collections-nice.582.mcz" target="_blank">http://source.squeak.org/trunk/Collections-nice.582.mcz</a><br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; ==================== Summary ====================<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Name: Collections-nice.582<br>
&gt;&gt;&gt;&gt; Author: nice<br>
&gt;&gt;&gt;&gt; Time: 19 September 2014, 10:22:13.338 pm<br>
&gt;&gt;&gt;&gt; UUID: 52a598f1-224e-4649-a95f-4e78547b5ed5<br>
&gt;&gt;&gt;&gt; Ancestors: Collections-nice.581<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Port TAG-SortFunctions of Travis Griggs from Cincom public store -<br>
&gt;&gt;&gt;&gt; version (11,tgriggs)<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Note that no collation policy were used for String.<br>
&gt;&gt;&gt;&gt; The spaceship operator &lt;=&gt; is also required in Kernel-Numbers.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; See also the blog<br>
&gt;&gt;&gt;&gt; <a href="http://objology.blogspot.fr/2010/11/tag-sortfunctions.html" target="_blank">http://objology.blogspot.fr/2010/11/tag-sortfunctions.html</a><br>
&gt;&gt;&gt;&gt;  and <a href="http://objology.blogspot.fr/2010/11/tag-sortfunctions-redux.html" target="_blank">http://objology.blogspot.fr/2010/11/tag-sortfunctions-redux.html</a><br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Note about the cost of these sort functions:<br>
&gt;&gt;&gt;&gt; as shown by this mini-bench on cog, using a Symbol costs a bit more<br>
&gt;&gt;&gt;&gt; (perform:) than a block activation, and monadic block a bit more than<br>
&gt;&gt;&gt;&gt; dyadic one because activated twice more, but it seems acceptable to me<br>
&gt;&gt;&gt;&gt; with regard to the great simplification and expressiveness of code :<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; | collec1 collec2 collec3 |<br>
&gt;&gt;&gt;&gt; collec1 := (1 to: 200000) collect: [:i | 1000000 atRandom-500000].<br>
&gt;&gt;&gt;&gt; collec2 := collec1 copy.<br>
&gt;&gt;&gt;&gt; collec3 := collec1 copy.<br>
&gt;&gt;&gt;&gt; {<br>
&gt;&gt;&gt;&gt; [collec1 sort: [:a :b | a abs &lt; b abs]] timeToRun.<br>
&gt;&gt;&gt;&gt; [collec2 sort: [:e | e abs] ascending] timeToRun.<br>
&gt;&gt;&gt;&gt; [collec3 sort: #abs ascending] timeToRun.<br>
&gt;&gt;&gt;&gt; }<br>
&gt;&gt;&gt;&gt;  #(345 532 912)<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; =============== Diff against Collections-nice.581 ===============<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + SortFunction subclass: #ChainedSortFunction<br>
&gt;&gt;&gt;&gt; +       instanceVariableNames: &#39;next&#39;<br>
&gt;&gt;&gt;&gt; +       classVariableNames: &#39;&#39;<br>
&gt;&gt;&gt;&gt; +       poolDictionaries: &#39;&#39;<br>
&gt;&gt;&gt;&gt; +       category: &#39;Collections-Support&#39;!<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + !ChainedSortFunction commentStamp: &#39;nice 3/13/2014 22:25&#39; prior: 0!<br>
&gt;&gt;&gt;&gt; + I add to my parent the idea of a &quot;next&quot; function to use when two<br>
&gt;&gt;&gt;&gt; objects are equal by my particular collator.<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + Usage<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + SortFunctions can be chained together in primary, secondary,<br>
&gt;&gt;&gt;&gt; tertiary, etc order using the comma method. Consider a sequence of<br>
&gt;&gt;&gt;&gt; customer objects, where each customer object responds to the messages<br>
&gt;&gt;&gt;&gt; firstName, lastName, and age. If we want to sort them lastName first,<br>
&gt;&gt;&gt;&gt; then firstName, and finally oldest first, we would use an expression<br>
&gt;&gt;&gt;&gt; like:<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + customers sort: #lastName ascending, #firstName ascending, #age<br>
&gt;&gt;&gt;&gt; descending<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + As noted in my super&#39;s comment, unary symbols or single arg blocks<br>
&gt;&gt;&gt;&gt; can be used. One can omit the the ascending methods on arguments (not<br>
&gt;&gt;&gt;&gt; the receiver), it will default blocks or symbols to be ascending if<br>
&gt;&gt;&gt;&gt; none is specified. In other words, the above expression could be<br>
&gt;&gt;&gt;&gt; simplified slightly as<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + customers sort: #lastName ascending, #firstName, #age descending<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + (note the missing ascending on the #firstName argument)<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + Instance Variables<br>
&gt;&gt;&gt;&gt; +       next    &lt;SortFunction&gt;  the next SortFunction to evaluate in<br>
&gt;&gt;&gt;&gt; the event my evaluator results in equal values.<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + !<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: ChainedSortFunction&gt;&gt;, (in category &#39;converting&#39;)<br>
&gt;&gt;&gt;&gt; -----<br>
&gt;&gt;&gt;&gt; + , aSortFunction<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       self next: next , aSortFunction!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: ChainedSortFunction&gt;&gt;next: (in category<br>
&gt;&gt;&gt;&gt; &#39;initialize-release&#39;) -----<br>
&gt;&gt;&gt;&gt; + next: anObject<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       next := anObject!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: ChainedSortFunction&gt;&gt;value:value: (in category<br>
&gt;&gt;&gt;&gt; &#39;evaluating&#39;) -----<br>
&gt;&gt;&gt;&gt; + value: anObject value: bObject<br>
&gt;&gt;&gt;&gt; +       &quot;Refinement of the parent behavior. If the result of my<br>
&gt;&gt;&gt;&gt; collator is 0, then pass on to the next variable to work it out.&quot;<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       | result |<br>
&gt;&gt;&gt;&gt; +       result := (collator value: anObject value: bObject) *<br>
&gt;&gt;&gt;&gt; direction.<br>
&gt;&gt;&gt;&gt; +       ^result isZero<br>
&gt;&gt;&gt;&gt; +               ifTrue: [next value: anObject value: bObject]<br>
&gt;&gt;&gt;&gt; +               ifFalse: [result &lt; 0]!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + Object subclass: #SortFunction<br>
&gt;&gt;&gt;&gt; +       instanceVariableNames: &#39;direction collator&#39;<br>
&gt;&gt;&gt;&gt; +       classVariableNames: &#39;&#39;<br>
&gt;&gt;&gt;&gt; +       poolDictionaries: &#39;&#39;<br>
&gt;&gt;&gt;&gt; +       category: &#39;Collections-Support&#39;!<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + !SortFunction commentStamp: &#39;nice 3/13/2014 22:24&#39; prior: 0!<br>
&gt;&gt;&gt;&gt; + I am intended to be used in place of two arg sort blocks.<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + Usage<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + In the following example, an ascending SortFunction is created based<br>
&gt;&gt;&gt;&gt; on the result of the #first message send to each object.<br>
&gt;&gt;&gt;&gt; + #(#(1 2) #(2 3) #(0 0)) sorted: #first ascending.<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + To sort by the #last element, but descending, the following would be<br>
&gt;&gt;&gt;&gt; used:<br>
&gt;&gt;&gt;&gt; + #(#(1 2) #(2 3) #(0 0)) sorted: #last descending.<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + One can use blocks as well. The following sorts in descending order,<br>
&gt;&gt;&gt;&gt; the sub elements based on the sum of their values.<br>
&gt;&gt;&gt;&gt; + | sumBlock |<br>
&gt;&gt;&gt;&gt; + sumBlock := [:sequence | sequence inject: 0 into: [:sum :each | sum<br>
&gt;&gt;&gt;&gt; + each]].<br>
&gt;&gt;&gt;&gt; + #(#(1 2) #(2 3) #(0 0)) sorted: sumBlock descending.<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + One can even use 2 arg blocks, for those cases where the function<br>
&gt;&gt;&gt;&gt; isn&#39;t expressible with objects that respond to &lt; and =. The only<br>
&gt;&gt;&gt;&gt; catch, is that such a function has to return not true and false, but<br>
&gt;&gt;&gt;&gt; instead a collation order, values of -1 (for before), 0 (the same) or<br>
&gt;&gt;&gt;&gt; 1 (to follow). For example:<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + | oddBlock |<br>
&gt;&gt;&gt;&gt; + oddBlock :=<br>
&gt;&gt;&gt;&gt; +               [:a :b |<br>
&gt;&gt;&gt;&gt; +               a odd = b odd ifTrue: [0] ifFalse: [a odd ifTrue: [-1]<br>
&gt;&gt;&gt;&gt; ifFalse: [1]]].<br>
&gt;&gt;&gt;&gt; + #(1 5 1 3 2 7 9 4 6) asSortedCollection: oddBlock descending<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + Instance Variables<br>
&gt;&gt;&gt;&gt; +       collator        &lt;BlockClosure&gt;  This is the collation function<br>
&gt;&gt;&gt;&gt; that must return a -1, 0, or 1. It is usually composed by an<br>
&gt;&gt;&gt;&gt; initialization method such as sendMessage: or monadicBlock:, but may<br>
&gt;&gt;&gt;&gt; be set directly.<br>
&gt;&gt;&gt;&gt; +       direction       &lt;SmallInteger&gt;  1 for ascending, -1 for<br>
&gt;&gt;&gt;&gt; descending<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; + !<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction class&gt;&gt;ascend (in category &#39;instance<br>
&gt;&gt;&gt;&gt; creation&#39;) -----<br>
&gt;&gt;&gt;&gt; + ascend<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       ^self new ascend!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction class&gt;&gt;descend (in category &#39;instance<br>
&gt;&gt;&gt;&gt; creation&#39;) -----<br>
&gt;&gt;&gt;&gt; + descend<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       ^self new descend!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction&gt;&gt;, (in category &#39;converting&#39;) -----<br>
&gt;&gt;&gt;&gt; + , aSortFunction<br>
&gt;&gt;&gt;&gt; +       &quot;Return a new SortFunction which is the concatenation of<br>
&gt;&gt;&gt;&gt; aSortFunction to me, I will be the primary sort, but if I compare<br>
&gt;&gt;&gt;&gt; equal, I will defer to the argument.&quot;<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       ^(ChainedSortFunction new)<br>
&gt;&gt;&gt;&gt; +               collator: collator;<br>
&gt;&gt;&gt;&gt; +               direction: direction;<br>
&gt;&gt;&gt;&gt; +               next: aSortFunction asSortFunction!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction&gt;&gt;asSortFunction (in category<br>
&gt;&gt;&gt;&gt; &#39;converting&#39;) -----<br>
&gt;&gt;&gt;&gt; + asSortFunction<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       ^self!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction&gt;&gt;ascend (in category<br>
&gt;&gt;&gt;&gt; &#39;initailize-release&#39;) -----<br>
&gt;&gt;&gt;&gt; + ascend<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       direction := 1!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction&gt;&gt;collator: (in category<br>
&gt;&gt;&gt;&gt; &#39;initailize-release&#39;) -----<br>
&gt;&gt;&gt;&gt; + collator: a2ArgBlock<br>
&gt;&gt;&gt;&gt; +       &quot;a2ArgBlock MUST return the collation order, -1, 0, or 1&quot;<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       collator := a2ArgBlock!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction&gt;&gt;descend (in category<br>
&gt;&gt;&gt;&gt; &#39;initailize-release&#39;) -----<br>
&gt;&gt;&gt;&gt; + descend<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       direction := -1!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction&gt;&gt;direction: (in category<br>
&gt;&gt;&gt;&gt; &#39;initailize-release&#39;) -----<br>
&gt;&gt;&gt;&gt; + direction: anInteger<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       direction := anInteger!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction&gt;&gt;isAscending (in category &#39;testing&#39;)<br>
&gt;&gt;&gt;&gt; -----<br>
&gt;&gt;&gt;&gt; + isAscending<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       ^direction = 1!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction&gt;&gt;isDescending (in category &#39;testing&#39;)<br>
&gt;&gt;&gt;&gt; -----<br>
&gt;&gt;&gt;&gt; + isDescending<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       ^direction = -1!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction&gt;&gt;monadicBlock: (in category<br>
&gt;&gt;&gt;&gt; &#39;initailize-release&#39;) -----<br>
&gt;&gt;&gt;&gt; + monadicBlock: aSingleArgBlock<br>
&gt;&gt;&gt;&gt; +       &quot;Initialze the receiver&#39;s collation block to compare the<br>
&gt;&gt;&gt;&gt; results of evaluating aSingleArgBlock with each argument, and then<br>
&gt;&gt;&gt;&gt; collate the return values with the &lt;=&gt; method.&quot;<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       collator := [:a :b | (aSingleArgBlock value: a) &lt;=&gt;<br>
&gt;&gt;&gt;&gt; (aSingleArgBlock value: b)]!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction&gt;&gt;sendMessage: (in category<br>
&gt;&gt;&gt;&gt; &#39;initailize-release&#39;) -----<br>
&gt;&gt;&gt;&gt; + sendMessage: aUnarySymbol<br>
&gt;&gt;&gt;&gt; +       &quot;Initialze the receiver&#39;s collation block to compare the<br>
&gt;&gt;&gt;&gt; results of sending aUnarySymbol to each argument, and then collate<br>
&gt;&gt;&gt;&gt; them with the &lt;=&gt; method.&quot;<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       collator := [:a :b | (a perform: aUnarySymbol) &lt;=&gt; (b perform:<br>
&gt;&gt;&gt;&gt; aUnarySymbol)]!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction&gt;&gt;toggleDirection (in category<br>
&gt;&gt;&gt;&gt; &#39;converting&#39;) -----<br>
&gt;&gt;&gt;&gt; + toggleDirection<br>
&gt;&gt;&gt;&gt; +       &quot;Invert my current direction, if I&#39;m currently ascending, this<br>
&gt;&gt;&gt;&gt; will cause me to be descending now, and vice-versa.&quot;<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       direction := direction * -1!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: SortFunction&gt;&gt;value:value: (in category &#39;evaluating&#39;)<br>
&gt;&gt;&gt;&gt; -----<br>
&gt;&gt;&gt;&gt; + value: anObject value: bObject<br>
&gt;&gt;&gt;&gt; +       &quot;Masquerade as a two argument block, used by many of the<br>
&gt;&gt;&gt;&gt; sorting APIs, by returning whether anObject should be placed before<br>
&gt;&gt;&gt;&gt; bObject or not.&quot;<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       | result |<br>
&gt;&gt;&gt;&gt; +       result := (collator value: anObject value: bObject) *<br>
&gt;&gt;&gt;&gt; direction.<br>
&gt;&gt;&gt;&gt; +       ^result &lt;= 0!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: String&gt;&gt;&lt;=&gt; (in category &#39;sorting&#39;) -----<br>
&gt;&gt;&gt;&gt; + &lt;=&gt; aCharacterArray<br>
&gt;&gt;&gt;&gt; +       &quot;Return a collation order of -1, 0, or 1, indicating whether I<br>
&gt;&gt;&gt;&gt; should be collated before the receiver, am equal, or after.<br>
&gt;&gt;&gt;&gt; +       See also:  <a href="http://en.wikipedia.org/wiki/Spaceship_operator" target="_blank">http://en.wikipedia.org/wiki/Spaceship_operator</a>&quot;<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       ^self = aCharacterArray<br>
&gt;&gt;&gt;&gt; +               ifTrue: [ 0 ]<br>
&gt;&gt;&gt;&gt; +               ifFalse: [self &lt; aCharacterArray<br>
&gt;&gt;&gt;&gt; +                       ifTrue: [ -1 ]<br>
&gt;&gt;&gt;&gt; +                       ifFalse: [ 1 ]]!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: Symbol&gt;&gt;asSortFunction (in category &#39;sorting&#39;) -----<br>
&gt;&gt;&gt;&gt; + asSortFunction<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       ^self ascending!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: Symbol&gt;&gt;ascending (in category &#39;sorting&#39;) -----<br>
&gt;&gt;&gt;&gt; + ascending<br>
&gt;&gt;&gt;&gt; +       &quot;Return a SortFunction around the receiver, where the receiver<br>
&gt;&gt;&gt;&gt; will be used as a unary message to send to both a and b during<br>
&gt;&gt;&gt;&gt; sorting, and then the result of said send will be collated in<br>
&gt;&gt;&gt;&gt; ascending order using the &lt;=&gt; method.&quot;<br>
&gt;&gt;&gt;&gt; +       &quot;Example: #(&#39;abc&#39;  &#39;de&#39; &#39;fghi&#39;) sorted: #size asscending&quot;<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       ^SortFunction ascend sendMessage: self!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: Symbol&gt;&gt;descending (in category &#39;sorting&#39;) -----<br>
&gt;&gt;&gt;&gt; + descending<br>
&gt;&gt;&gt;&gt; +       &quot;Return a SortFunction around the receiver, where the receiver<br>
&gt;&gt;&gt;&gt; will be used as a unary message to send to both a and b during<br>
&gt;&gt;&gt;&gt; sorting, and then the result of said send will be collated in<br>
&gt;&gt;&gt;&gt; descending order using the &lt;=&gt; method.&quot;<br>
&gt;&gt;&gt;&gt; +       &quot;Example: #(&#39;abc&#39;  &#39;de&#39; &#39;fghi&#39;) sorted: #size descending&quot;<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       ^SortFunction descend sendMessage: self!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Item was added:<br>
&gt;&gt;&gt;&gt; + ----- Method: Text&gt;&gt;&lt;=&gt; (in category &#39;sorting&#39;) -----<br>
&gt;&gt;&gt;&gt; + &lt;=&gt; aCharacterArray<br>
&gt;&gt;&gt;&gt; +       &quot;Return a collation order of -1, 0, or 1, indicating whether I<br>
&gt;&gt;&gt;&gt; should be collated before the receiver, am equal, or after.<br>
&gt;&gt;&gt;&gt; +       See also:  <a href="http://en.wikipedia.org/wiki/Spaceship_operator" target="_blank">http://en.wikipedia.org/wiki/Spaceship_operator</a>&quot;<br>
&gt;&gt;&gt;&gt; +<br>
&gt;&gt;&gt;&gt; +       ^string = aCharacterArray<br>
&gt;&gt;&gt;&gt; +               ifTrue: [ 0 ]<br>
&gt;&gt;&gt;&gt; +               ifFalse: [string &lt; aCharacterArray asString<br>
&gt;&gt;&gt;&gt; +                       ifTrue: [ -1 ]<br>
&gt;&gt;&gt;&gt; +                       ifFalse: [ 1 ]]!<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;<br>
<br>
<br>
<br>
</div></div></blockquote></div><br></div></div>