<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;">
[squeak-dev] Collection>>sum implementation


Jason Johnson jason.johnson.081 at gmail.com 
Mon Aug 11 11:57:54 UTC 2008 


Hi Jason,

I remember debugging an instance of this problem a while back.


Ah found it:
http://bugs.squeak.org/view.php?id=6560
[BUG][FIX] "{Color red. Color green. Color blue} sum" can't return "Color white"


The solution was to inject the zero element then sum the whole list.

How do you get a zero element when you don't know what you are dealing with?

You let it tell you:

any := myCollection anyone  .
zeroElement := any - any .

answer := 
 myCollection inject: zeroElement into: [ :sum :each | sum + each ] .

The mantis report needs to be harvested.


Hth,

Yours in curiosity and service, --Jerome Peace

***
Jason>Hello all,
Jason>
Jason>In my explorations today I happened on the implementation of the #sum
Jason>method:
Jason>
Jason>Collection>>sum
Jason>        "This is implemented using a variant of the normal inject:into: pattern.
Jason>        The reason for this is that it is not known whether we're in the normal
Jason>        number line, i.e. whether 0 is a good initial value for the sum.
Jason>        Consider a collection of measurement objects, 0 would be the unitless
Jason>        value and would not be appropriate to add with the unit-ed objects."
Jason>        | sum sample |
Jason>        sample _ self anyOne.
Jason>        sum _ self inject: sample into: [:accum :each | accum + each].
Jason>        ^ sum - sample
Jason>
Jason>
Jason>Personally, I view the code in the core image to, among other things,
Jason>serve the role of showing new Smalltalk programmers good ways of using
Jason>the language.  This is exactly the kind of thing I would *not* want
Jason>people to see.
Jason>
Jason>The obvious issue here is that #inject:into: doesn't fit this case
Jason>very well.  But rather then go to these kinds of steps a much better
Jason>solution would be to simply notice that a specialized variation of
Jason>#inject:into: (that is in fact  quite common) is needed here.  Namely
Jason>a reduction method that just uses the first element as the starting
Jason>value, conceptually:
Jason>
Jason>Collection>>reduce: aBlock
Jason>      ^ self allButFirst inject: self first into: aBlock
Jason>
Jason>As it turns out there exists a more efficient implementation of this
Jason>method in Lukas' Magritte-Model package.  I would propose his method
Jason>be promoted to a core method so #sum could be rewritten as:
Jason>
Jason>sum
Jason>     "sum the reciever"
Jason>     ^ self reduce: [:accum :each| accum + each ]
Jason>
Jason>Thanks,
Jason>Jason
***
</td></tr></table><br>