[squeak-dev] The Trunk: Collections-nice.582.mcz

David T. Lewis lewis at mail.msen.com
Mon Sep 22 18:12:28 UTC 2014


No, no, sorry I did not mean to cause alarm! Thanks for contacting Travis.
I don't know him but I'm sure he will be happy to help us, so let's just
wait for his reply.

Thanks for following up on this, much appreciated.

Dave


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




More information about the Squeak-dev mailing list