Issue #12217 has been updated by Akira Tanaka.

File inject-plus.txt added

I think sum of elements of an enumerable is used in many situations.

I searched '\.inject[ \(\{]' and '+' in .rb files in gems:
inject-plus.txt

It seems .inject(:+) is an idiom for summation.

```
% fgrep '.inject(:+)' inject-plus.txt|wc -l
1040
% fgrep '.inject(&:+)' inject-plus.txt|wc -l
446
% fgrep '.inject(0, :+)' inject-plus.txt|wc -l
138
% fgrep '.inject(0, &:+)' inject-plus.txt|wc -l
90
% fgrep '.inject(0.0, :+)' inject-plus.txt|wc -l 
13
% fgrep '.inject(0.0, &:+)' inject-plus.txt|wc -l
23
```

It seems .inject {|s,e| s + e} is also used.

```
% grep '.inject(0) *{|\([a-z0-9]\+\), *\([a-z0-9]\+\)| *\1 *+ *\2 *}' inject-plus.txt|wc -l
311
% grep '.inject *{|\([a-z0-9]\+\), *\([a-z0-9]\+\)| *\1 *+ *\2 *}' inject-plus.txt|wc -l  
213
% grep '.inject(0.0) *{|\([a-z0-9]\+\), *\([a-z0-9]\+\)| *\1 *+ *\2 *}' inject-plus.txt|wc -l
27
```

I think Enumerable#sum is useful:
- Enumerable#sum is shorter than Enumerable#inject(:+) ant it makes code succinct.
- it can return 0 for empty enumerable.  It makes us to avoid bugs on empty enumerable.
- more accurate for sum of Floats by Kahan's compensated summation algorithm (as muraken said)
- faster than Enumerable#inject(:+) (Enumerable#inject(:+) will also be faster since Ruby 2.4, though)

However it has a problem:
- Enumerable#sum is not well defined for non-numeric elements, especially objects without + method.


----------------------------------------
Feature #12217: Introducing Enumerable#sum for precision compensated summation and revert r54237
https://bugs.ruby-lang.org/issues/12217#change-57697

* Author: Kenta Murata
* Status: Assigned
* Priority: Normal
* Assignee: Yukihiro Matsumoto
----------------------------------------
In this issue I propose to introduce Enumerable#sum for precision compensated summation of an array of floating point numbers.

In r54237, I've changed Enumerable#inject to support precision compensated summation for summing up floating point numbers.
But I noticed that this commit broke the equality of `ary.inject(:+) == ary.inject {|a, x| a + x }`.
I think this equality is important property of inject method, so I don't want to break it.

And because precision compensated algorithms are complicated, I think they are provided in the standard library, especially simple summation.


---Files--------------------------------
inject-plus.txt (1.21 MB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>