Introducing `for-let` and `for-reduce`

Coming from an imperative background, I had restraints towards for and always preferred Enum. But this part from the original proposal (I suggest looking at the problem stated there) changed my mind:

Comprehensions

Comprehensions in Elixir have always been a syntax sugar to more complex data-structure traversals. Do you want to have the cartersian product between all points in x and y? You could write this:

Enum.flat_map(x, fn i ->
 Enum.map(y, fn j -> {i, j} end)
end)

Or with a comprehension:

for i <- x, j <- y, do: {i, j}

Or maybe you want to brute force your way into finding Pythagorean Triples?

Enum.flat_map(1..20, fn a ->
 Enum.flat_map(1..20, fn b ->
   1..20
   |> Enum.filter(fn c -> a*a + b*b == c*c end)
   |> Enum.map(fn c -> {a, b, c} end)
 end)
end)

Or with a comprehension:

for a <- 1..20,
   b <- 1..20,
   c <- 1..20,
   a*a + b*b == c*c,
   do: {a, b, c}

There is no question the comprehensions are more concise and clearer, once you understand their basic syntax elements (which are, at this point, common to many languages).
As mentioned in the introduction, we can express map, filter, reduce, and collect inside comprehensions. But how can we represent map_reduce in a clear and concise way?

I began to see where I can apply for to make the code cleaner. See here.

You don’t actually need for, but learning it - including the newest additions - will make your code better. I’m really looking forward to this and even more to a way to early-exit the comprehension so that I can get rid of all the not-so-pretty Enum.reduce_while calls.

2 Likes