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 <Smalltalk@jgfoster.net> wrote:
On Mar 23, 2020, at 6:06 AM, Sven Van Caekenberghe <sven@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