Enum.sum/2

65 views
Skip to first unread message

Sean Handley

unread,
Dec 1, 2018, 11:18:58 AM12/1/18
to elixir-lang-core
Hello,

I'd like to propose Enum.sum/2, where the second argument is a function.

This will allow writing

Enum.sum([1, 2, 3], &(&1 * 2))

instead of
 
Enum.map([1,2,3], &(&1 * 2)) |> Enum.sum()

The advantages are:

- Write less code.
- One few iteration across the collection.


Please let me know your thoughts.

Cheers,
Sean

Parker Selbert

unread,
Dec 1, 2018, 11:27:28 AM12/1/18
to elixir-l...@googlegroups.com
I can't help but think that this request and the earlier doc improvements to `Enum.reduce_while/3` are stemming from the first challenge in the Advent of Code.

Anyhow, is `Enum.sum/2` that much more expressive than `Enum.reduce/3`?

Enum.reduce([1, 2, 3], 0, &(&1 * 2 + &2))

— Parker

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Sean Handley

unread,
Dec 1, 2018, 11:40:21 AM12/1/18
to elixir-lang-core
I think it depends what you're used to.

The Enumerable module in Ruby has a lot of methods like this that accept a block. It's syntactical sugar, for sure. But I'm a fan of it because I can mentally parse its intentions faster than a reduce (which could really be doing *anything*).

Sean Handley

unread,
Dec 1, 2018, 11:40:58 AM12/1/18
to elixir-lang-core
And yes, you're right about Advent Of Code! :-)


On Saturday, 1 December 2018 16:27:28 UTC, Parker Selbert wrote:

Xavier Noria

unread,
Dec 1, 2018, 12:37:12 PM12/1/18
to elixir-l...@googlegroups.com
On Sat, Dec 1, 2018 at 5:27 PM Parker Selbert <par...@sorentwo.com> wrote:

I can't help but think that this request and the earlier doc improvements to `Enum.reduce_while/3` are stemming from the first challenge in the Advent of Code.

Confirm re PR.

Alexei Sholik

unread,
Dec 2, 2018, 1:53:02 PM12/2/18
to elixir-l...@googlegroups.com
The first advantage (write less code) is defeated by adding one more function to the module, thereby increasing the API surface.

As for the second one, this code does one pass through the list:

Stream.map([1,2,3], & &1*2) |> Enum.sum

Sean Handley

unread,
Dec 2, 2018, 3:07:55 PM12/2/18
to elixir-lang-core
Ok, I can accept that. I'd like to rephrase the advantage:

- Write code with clearer intentions.

Contrived examples are all quite easy to fathom, but I like seeing Enum.sum(collection, fun) where the function decides whether to include the given element in the summation. It's like a slightly more intelligent Enum.filter/2

Also, I'd say the same syntactic sugar could apply also to Enum.count/1 and probably several others.

Ben Wilson

unread,
Dec 2, 2018, 9:19:39 PM12/2/18
to elixir-lang-core
I don't really agree that it makes the intent clearer. It combines two distinct and unrelated activities. One takes the sum of a list, the other maps each value in a list to some other value. list |> Enum.map(& &1 * 2) |> Enum.sum expresses this perfectly. If you're going for lolspeed and need to avoid the second pass then you want a bare recursive function anyway and shouldn't even use Enum.

Louis Pilfold

unread,
Dec 3, 2018, 5:34:53 AM12/3/18
to elixir-l...@googlegroups.com
Hi

If this function were to exist I think we would need to call it `sum_map/2`, as the combination of `sum` and `map`. Previously we had `Enum.filter_map/2`, though it was deprecated in favour of `Enum.filter/2` and `Enum.map/2`. The trend is that we are removing these combined Enum functions rather than adding them, so it seems unlikely that we would add this new kind of `sum` if we continued this debate.

A good point from Ben, the polymorphic nature of Enum and the Enumerable protocol means it is slower than using the List module or writing recursive functions, so for this kind of performance tuning the Enum module is probably not the right place to start.

Cheers,
Louis

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages