NumericalCollections

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

NumericalCollections

Nicolas Cellier-3
Hello,
I published my propositions for NumericalCollection extensions (see this
package on cincom public store).

These are so obvious (exist in F95, Matlab, etc...) and perfectly find their
place here.
 #sum:
  (1 to: 5) sum: [:e | 2**e].
 #product #product:
  (1 to: 5) product.
 #cumulativeSum #cumulativeSum:
 #cumulativeProduct #cumulativeProduct:
  (1 to: 5) cumulativeSum: [:e | 2**e].
 #maxOf: #minOf:
  #(-4 2 -9 7) maxOf: [:e | e abs].
 #findMax findMaxOf:
 #findMin #findMinOf:
  #(-4 2 -9 7) findMaxOf: [:e | e abs].
 #cumulativeMax #cumulativeMaxOf:
 #cumulativeMin #cumulativeMinOf:
  #(-4 2 -9 7) cumulativeMax: [:e | e abs].

GeometricInterval:
 (1 to: 16 ratio: 2) asArray.
 #ratios is defined by similarity with #steps
  (these selectors should be redefined in Interval and GeometricInterval...)

IndirectCollection: mostly same as ReindexedCollection, but more general (not
limited to Interval - weren't there a MappedCollection in st-80 ?).

Comments:
 #max: would conflict semantic of Magnitude>>max:, better use maxOf:
 should we use #sumOf: instead of sum ?
 same for #productOf: #cumulativeSumOf: #cumulativeProductOf: ...

Nicolas Cellier (nice)

Reply | Threaded
Open this post in threaded view
|

Re: NumericalCollections

Vincent Ginot
Nice, many thanks !

Le 6 févr. 06, à 22:37, nicolas cellier a écrit :

> Hello,
> I published my propositions for NumericalCollection extensions (see
> this
> package on cincom public store).
>
> These are so obvious (exist in F95, Matlab, etc...) and perfectly find
> their
> place here.
>  #sum:
>   (1 to: 5) sum: [:e | 2**e].
>  #product #product:
>   (1 to: 5) product.
>  #cumulativeSum #cumulativeSum:
>  #cumulativeProduct #cumulativeProduct:
>   (1 to: 5) cumulativeSum: [:e | 2**e].
>  #maxOf: #minOf:
>   #(-4 2 -9 7) maxOf: [:e | e abs].
>  #findMax findMaxOf:
>  #findMin #findMinOf:
>   #(-4 2 -9 7) findMaxOf: [:e | e abs].
>  #cumulativeMax #cumulativeMaxOf:
>  #cumulativeMin #cumulativeMinOf:
>   #(-4 2 -9 7) cumulativeMax: [:e | e abs].
>
> GeometricInterval:
>  (1 to: 16 ratio: 2) asArray.
>  #ratios is defined by similarity with #steps
>   (these selectors should be redefined in Interval and
> GeometricInterval...)
>
> IndirectCollection: mostly same as ReindexedCollection, but more
> general (not
> limited to Interval - weren't there a MappedCollection in st-80 ?).
>
> Comments:
>  #max: would conflict semantic of Magnitude>>max:, better use maxOf:
>  should we use #sumOf: instead of sum ?
>  same for #productOf: #cumulativeSumOf: #cumulativeProductOf: ...
>
> Nicolas Cellier (nice)
>
>

Reply | Threaded
Open this post in threaded view
|

Re: NumericalCollections

Travis Griggs
In reply to this post by Nicolas Cellier-3
On Feb 6, 2006, at 13:37, nicolas cellier wrote:

> Hello,
> I published my propositions for NumericalCollection extensions (see  
> this
> package on cincom public store).

Nicolas, I wrote the original versions. We use this stuff all the  
time in our app. Cool to see it evolving some.

>
> These are so obvious (exist in F95, Matlab, etc...) and perfectly  
> find their
> place here.
>  #sum:
>   (1 to: 5) sum: [:e | 2**e].
>  #product #product:
>   (1 to: 5) product.
>  #cumulativeSum #cumulativeSum:
>  #cumulativeProduct #cumulativeProduct:
>   (1 to: 5) cumulativeSum: [:e | 2**e].
>  #maxOf: #minOf:
>   #(-4 2 -9 7) maxOf: [:e | e abs].
>  #findMax findMaxOf:
>  #findMin #findMinOf:
>   #(-4 2 -9 7) findMaxOf: [:e | e abs].
>  #cumulativeMax #cumulativeMaxOf:
>  #cumulativeMin #cumulativeMinOf:
>   #(-4 2 -9 7) cumulativeMax: [:e | e abs].

I looked at these. They all look cool. The cumulative things could be  
implemented as:

cumulativeSum
| sum |
sum := self first - self first. "compute the natural 0 value for the  
contained elements"
^self collect: [:each | sum := sum + each]

The various *Of: transforms are interesting to me. It's definitely  
terser than the variant that does the collect:. Is the goal for  
terseness? The only issue you get into is where do you draw the line.  
It's like the extensions where people implement and:ifTrue:ifFalse:.  
The amount of them is endless, and every domain/problem has its own  
set, so how do you decide that sumOf: is worthy inclusion in a  
general purpose library, but not absOf: (for example). Or is the  
motivation of these for speed/efficiency. Every collect: creates a  
throwaway collection. With lots of repetition or large collections,  
this may actually become noticeably wasteful. In *that* case.... is  
there a more general purpose pattern at stake here. Basically, I want  
to create an object which represents f(x) on a collection (not the  
result of a applying f(x) to the collection) and then have it respond  
to the already existent methods. I'm not sure what you'd call the  
wrapper object, or a good short method to create it, but you'd end up  
with something like:

(#(1 2 3 4 5 6 7) compute: [:e | e * 10]) max

The compute doesn't actually do the computation, it creates the  
wrapper. It implements at: as

at: anIndex
        ^function value: (input at: anIndex)

and then it just inherits max and all other methods from collection,  
and it just works. Then you don't have to add an +of:.

What do you think of that?

>
> GeometricInterval:
>  (1 to: 16 ratio: 2) asArray.
>  #ratios is defined by similarity with #steps
>   (these selectors should be redefined in Interval and  
> GeometricInterval...)
>
> IndirectCollection: mostly same as ReindexedCollection, but more  
> general (not
> limited to Interval - weren't there a MappedCollection in st-80 ?).
>
> Comments:
>  #max: would conflict semantic of Magnitude>>max:, better use maxOf:
>  should we use #sumOf: instead of sum ?
>  same for #productOf: #cumulativeSumOf: #cumulativeProductOf: ...

I don't see a max: in the original... or are you saying you added  
one? So I'm not sure what it would do. Though I think I would want it  
to return a new collection where the elements had been max:'ed  
against each other. For example:

#(1 2 3 4 5) max: #(5 4 3 2 1) --> #(5 4 3 4 5). One of the things I  
found was to follow the direction Point has taken. I'm not saying its  
the mathematically correct thing to do even, just that it seems to  
have evolved the way it has, and sticking with the convention I found  
similar payoffs.

I prefer the terseness of being able to say someCollection sum. When  
I see sumOf: I think, "sumOf: what?"

--
Travis Griggs
Objologist
What's next, Intel Processors branded with "Apple Outside" stickers?



-----------------------------------------
DISCLAIMER: This email is bound by the terms and conditions
described at
http://www.key.net/disclaimer.htm

Reply | Threaded
Open this post in threaded view
|

Re: NumericalCollections

Nicolas Cellier-3
In reply to this post by Nicolas Cellier-3
In fact, as i already stated on squeak-dev, the sumOf: maxOf: ... messages are
not aboslutely necessary since inject:into: already exist.

But they add value because they are clearer than inject:into:.
Most senders of inject:into: are in fact used to do things like
 - merging collections
 - summing
 - finding max or min
 - counting number of elements satisfying a condition
To me, inject:into: is intention revealling...

For example:

participantsSize
 "Answer the size of the participants array."
 "Since the participants are a WeakArray, we also need to skip
 over 0 values (the death of a participant will leave a 0)."

 | total |
 participantsSemaphore critical:
  [ total := self participants
    inject: 0
    into: [:subTotal :next |
     next == 0 ifTrue: [ subTotal ] ifFalse: [ subTotal + 1] ] ].
 ^total

Can be rewritten
 total := self participants count: [:each | each ~= 0].

Implement a message like count: and you will refactor instantly ten senders,
getting a more legible understandable and shorter code.
And this is not concerning a specific application, it's deep in the image and
general purpose.

Of course, you have to be selective and put a brake on image growth, some
extensions are really useless, some really adding value, and some in-between.

and:ifTrue: would have hundred senders maybe, but does not really make code
shorter nor clearer. Beside, it's breaking bytecode optimization unless
wasting more time and efforts in Compiler.

Same question arise with squeak ifNil: ifNotNil: that add few value but has so
widely spread that you have to include it in VW for interoperability...

Now, you come with your excellent lazy evaluation and break my effects
 (#(1 2 3 4 5 6 7) compute: [:e | e * 10]) max

Knowing this, i am forced to reconsider my position and transfer these Of:
messages from adding value to in-between...

But at least count: should be there.

Reply | Threaded
Open this post in threaded view
|

Re: NumericalCollections

Nicolas Cellier-3
In reply to this post by Nicolas Cellier-3

Le Mardi 07 Février 2006 22:57, Travis Griggs a écrit :

> > Comments:
> >  #max: would conflict semantic of Magnitude>>max:, better use maxOf:
> >  should we use #sumOf: instead of sum ?
> >  same for #productOf: #cumulativeSumOf: #cumulativeProductOf: ...
>
> I don't see a max: in the original... or are you saying you added  
> one? So I'm not sure what it would do. Though I think I would want it  
> to return a new collection where the elements had been max:'ed  
> against each other. For example:
>
> #(1 2 3 4 5) max: #(5 4 3 2 1) --> #(5 4 3 4 5). One of the things I  
> found was to follow the direction Point has taken. I'm not saying its  
> the mathematically correct thing to do even, just that it seems to  
> have evolved the way it has, and sticking with the convention I found  
> similar payoffs.

That is exactly what i meaned, but i did not implement.
You would also do a convenient matlabish
    aCollection max: aNumber

Because i did not want to conflict in this eventaulity, i added the Of:
suffix.

Lot of stuff are not really mathematically correct, like
    aCollection + aNumber
they are just convenient and widely used due to matlab world.
What if you have a Collection of Collections ?

#( #(1 2) #(3 4) ) + #( 0 1 )
Will it answer
    #( #(1 2) #(4 5) )
Or will it answer
    #( #(1 3) #(3 5) )
What should it answer according to you ?
Without solid mathematical ground under our feet, generalization will not
 grow very far...

Where to stop Matlab/F95 mimetism ?
    aCollection < aNumber answers a collection of boolean ?
    aCollection < aCollection would conflict with String ordering for example
Also we would not override these to answer collections of boolean
    aCollection = aNumber
    aCollection = aCollection

Matlab has idioms we cannot adopt...
 < , = and > seems beyond the limit of what is acceptable.
max: is close to the limit of concessions we can pay (max: is related to

>...). Point implements it, you are right, but I would not take

responsibility alone to implement such one...

-------------------------------------------------------