https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112016-11-04T19:28:28ZRuby Issue Tracking SystemRuby master - Feature #12902: How about Enumerable#sum uses initial value rather than 0 as default?https://bugs.ruby-lang.org/issues/12902?journal_id=612442016-11-04T19:28:28ZAaronLasseigne (Aaron Lasseigne)aaron.lasseigne@gmail.com
<ul></ul><p>In <a href="https://bugs.ruby-lang.org/issues/12217#note-3" class="external">https://bugs.ruby-lang.org/issues/12217#note-3</a>, Akira Tanaka, mentions that the default argument to sum is 0. This creates problems with non-numeric summations (e.g. strings). I would like to suggest using the first enumerable value. This would make the method more flexible. It also makes it behave more like reduce. I think using the initial value in the enumerable is less surprising than using 0.</p>
<p>** I missed a sentence. :( **</p> Ruby master - Feature #12902: How about Enumerable#sum uses initial value rather than 0 as default?https://bugs.ruby-lang.org/issues/12902?journal_id=612682016-11-05T02:29:28Zakr (Akira Tanaka)akr@fsij.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Feedback</i></li></ul><p>I think [].sum should return 0.<br>
Returning 0 is better than nil because programmers don't need to treat empty array specially.<br>
This behavior is different with Enumerable#reduce which returns nil for empty array.</p>
<p>Also, string summation using Enumerable#sum is not good idea because it is slow.<br>
String#join is faster.<br>
So, we should not encourage Enumerable#sum for string summation.</p> Ruby master - Feature #12902: How about Enumerable#sum uses initial value rather than 0 as default?https://bugs.ruby-lang.org/issues/12902?journal_id=612822016-11-05T04:01:54Zduerst (Martin Dürst)duerst@it.aoyama.ac.jp
<ul></ul><p>On 2016/11/05 04:28, <a href="mailto:aaron.lasseigne@gmail.com" class="email">aaron.lasseigne@gmail.com</a> wrote:</p>
<blockquote>
<p>Issue <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: How about Enumerable#sum uses initial value rather than 0 as default? (Rejected)" href="https://bugs.ruby-lang.org/issues/12902">#12902</a> has been updated by Aaron Lasseigne.</p>
</blockquote>
<blockquote>
<p>In <a href="https://bugs.ruby-lang.org/issues/12217#note-3" class="external">https://bugs.ruby-lang.org/issues/12217#note-3</a>, Akira Tanaka, mentions that the default argument to sum is 0. This creates problems with non-numeric summations (e.g. strings). I would like to suggest using the first enumerable value. This would make the method more flexible. It also makes it behave more like reduce. I think using the initial value in the enumerable is less surprising than using 0.</p>
</blockquote>
<p>What would/should the behavior be for an empty array?</p> Ruby master - Feature #12902: How about Enumerable#sum uses initial value rather than 0 as default?https://bugs.ruby-lang.org/issues/12902?journal_id=613162016-11-05T14:35:58Zherwin (Herwin W)
<ul></ul><p>Akira Tanaka wrote:</p>
<blockquote>
<p>I think [].sum should return 0.<br>
Returning 0 is better than nil because programmers don't need to treat empty array specially.<br>
This behavior is different with Enumerable#reduce which returns nil for empty array.</p>
<p>Also, string summation using Enumerable#sum is not good idea because it is slow.<br>
String#join is faster.<br>
So, we should not encourage Enumerable#sum for string summation.</p>
</blockquote>
<p>I guess you mean Array#join</p>
<p>And the fact that Enumerable#sum could be used for string concatenation makes the default value of 0 pretty weird. Just imagine the following piece of code:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="s1">''</span><span class="p">]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">sum</span> <span class="o">=></span> <span class="s1">''</span>
<span class="n">a</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="s1">''</span><span class="p">)</span>
<span class="n">a</span><span class="p">.</span><span class="nf">sum</span> <span class="o">=></span> <span class="mi">0</span>
</code></pre>
<p>This just removes the special case of empty arrays for numeric values, but still doesn't help much with anything else (even though I agree that calculating a sum of strings is just stupid)</p> Ruby master - Feature #12902: How about Enumerable#sum uses initial value rather than 0 as default?https://bugs.ruby-lang.org/issues/12902?journal_id=614482016-11-11T20:31:24ZAaronLasseigne (Aaron Lasseigne)aaron.lasseigne@gmail.com
<ul></ul><p>Martin,</p>
<p>I would expect the empty to act like <code>reduce</code> and return <code>nil</code>.</p>
<p>Akira,</p>
<p>I agree that doing string concatenation with <code>sum</code> is a poor idea. It's just that this is on <code>Enumerable</code> which is supposed to allow iterations over whatever underlying data you want and this is favoring a particular type of underlying data. I do understand that <code>0</code> is convenient for the vast majority of use cases, it just feels like <code>Numeric</code> is creeping into <code>Enumerable</code>.</p>
<p>Thanks for considering it and responding.</p> Ruby master - Feature #12902: How about Enumerable#sum uses initial value rather than 0 as default?https://bugs.ruby-lang.org/issues/12902?journal_id=614492016-11-11T22:16:05Zbitsweat (Jeremy Daer)jeremydaer@gmail.com
<ul></ul><p>If we treated the first argument to <code>#sum</code> as the additive identity instead of "initial element," then it'd be very clear what to expect:</p>
<p>When there are no elements in the Enumerable, return the identity.</p>
<p>That works nicely for summing non-numeric/string/etc objects:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">payments</span><span class="p">.</span><span class="nf">none?</span> <span class="c1"># => true</span>
<span class="n">payments</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="no">Payment</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span> <span class="c1"># => Payment.new(0)</span>
</code></pre>
<p>Plus, it's backward compatible, doesn't break existing behavior.</p> Ruby master - Feature #12902: How about Enumerable#sum uses initial value rather than 0 as default?https://bugs.ruby-lang.org/issues/12902?journal_id=614572016-11-12T00:10:11Zakr (Akira Tanaka)akr@fsij.org
<ul><li><strong>Status</strong> changed from <i>Feedback</i> to <i>Rejected</i></li></ul><p>Jeremy Daer wrote:</p>
<blockquote>
<p>If we treated the first argument to <code>#sum</code> as the additive identity instead of "initial element," then it'd be very clear what to expect:</p>
</blockquote>
<p>I like current behavior than yours because the behavior can be explained simpler:<br>
Enumerable#sum returns initial + elem0 + elem1 + ... elemN.<br>
No need to distinguish empty and non-empty enumerable.</p>
<p>Yours needs more complex explanation.</p>
<blockquote>
<p>Plus, it's backward compatible, doesn't break existing behavior.</p>
</blockquote>
<p>Enumerable#sum and Array#sum is defined in many gems with different behaviors.<br>
Perfect backward compatibility is impossible.</p> Ruby master - Feature #12902: How about Enumerable#sum uses initial value rather than 0 as default?https://bugs.ruby-lang.org/issues/12902?journal_id=622062016-12-22T01:40:52Zioquatix (Samuel Williams)samuel@oriontransfer.net
<ul></ul><p>Just to add, this breaks code which uses facets.</p>
<p><a href="https://github.com/rubyworks/facets/issues/247" class="external">https://github.com/rubyworks/facets/issues/247</a></p>
<p>The method signature is:</p>
<pre><code>def sum(*identity, &block)
</code></pre>
<p>I think it's probably important to consider this use case.</p>