<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>