What's wrong with this definition? sum "(1) This used to use #runsDo:, which can lead to big savings on bags and runarrays, but we almost never use this method on them, so it didn't pay off. (2) The obvious initialisation to 0 doesn't work with a collection of Money, Quantities, Durations, and so on. (3) Since the receiver is almost always a collection of numbers, it would be very bad if #() sum did not answer 0. So we should not use #anyOne. (4) Using #anyOne to select between algorithms required being able to traverse the Enumerable twice, but Enumerable is for things you can only traverse once. Oops. Good thing we want to avoid #anyOne anyway. (5) nil does not and should not respondTo: #+ so we can use a single variable. Watch out for this in other summaries." |s| s := nil. self do: [:each | s := s ifNil: [each] ifNotNil: [each + s]]. ^s ifNil: [0] ifNotNil: [s]
On Tue, 24 Mar 2020 at 02:46, James Foster <smallt...@jgfoster.net> wrote: > > > > On Mar 23, 2020, at 6:06 AM, Sven Van Caekenberghe <s...@stfx.eu> wrote: > > > > What you found out now is that the clever trick used to avoid picking an > > additive identity (picking an element, counting it twice and then > > subtracting it) leads to a loss of precision when floating point numbers > > are involved. This is an important issue. > > If this approach is to be preserved, then each class should have an additive > identity so instead of adding and subtracting an object, we let the object > tell us its zero. > > James