iex> for n <- 1..4, do: n*n
[1, 4, 9, 16]
Or for your example: iex> l = 1..3 # equivalent to [1,2,3]
iex> Enum.reduce(l, fn item, acc -> acc + item end)
# or
iex> Enum.reduce(l, &(&1+&2)
# or the built in
iex> Enum.sum(l)
# all return:
6
https://elixir-lang.org/getting-started/comprehensions.html
https://hexdocs.pm/elixir/1.12/Enum.html#reduce/2
https://hexdocs.pm/elixir/1.12/Enum.html#sum/1None of which take away from your point though: it's definitely a different mental model than you use for Python/Go/Javascript.
I should have picked a different example -- the idea I was trying to get across was that mutability within a loop is useful.
Here’s a similar question I asked with Python vs. OCaml and Lisp. Short-circuiting loops seems to cause the code to become fairly ugly in functional languages
https://old.reddit.com/r/ProgrammingLanguages/comments/puao1...
sum_list = fn list ->
for item <- list,
reduce: 0,
do: (sum -> sum + item)
end
sum_list.([1,2,3])
Other comments are correct that `Enum.reduce/2` is probably better: Enum.reduce(list, &(&1 + &2))
Obviously you don't have the flexibility / mutability you refer to in other comments with either of these, but you can always put more in your accumulator: get_sum_and_update_count = fn list, map ->
for item <- list,
reduce: {0, map},
do: ({sum, map} -> {sum + item, Map.update(map, item, 1, &(&1 + 1))})
end
(A contrived function that returns a list sum and an updated map with the count of the values found in the list)Mutability within the loop is useful, and it can be controlled by processes and message passing.
Besides being in that magical sweet spot (executes imperatively but reads declaratively), a reduce forces you to declare ahead of time what things can be carried over and mutated between each iteration.
> it can be controlled by processes and message passing.
DO NOT DO THIS YOU WILL REGRET THIS SIMCITY MEME
Admittedly, I haven't worked with Erlang or Elixir, so their solution to this might be much more usable. Ray is aimed primarily at ML use-cases, though it is quite general.
I'm all for the immutable / message-passing architecture in the large, but I wish that you could just write Python-style code within processes. The VM copies all data structures at process boundaries anyway.
I think that language would be very popular!
I wrote Lisp 20 years ago, before Python, but now it feels a little annoying to "invert" all my code, for what seems like no benefit
e.g. from https://learnxinyminutes.com/docs/elixir/
I would rather just write But then also have the Erlang VM to schedule processes and pass immutable messages.There is obviously a builtin in Python that does this, and I'm sure there is a better way to do this in Elixir. But I think the general principle does hold.