For in Elixir
defmodule ForExample do
def run do
# The most basic type, with a single condition.
i = 1
for _ <- Stream.repeatedly(fn -> i <= 3 end), i <= 3 do
IO.puts(i)
i = i + 1
end
# A classic initial/condition/after loop.
Enum.each(0..2, fn j ->
IO.puts(j)
end)
# Another way of accomplishing the basic "do this
# N times" iteration is to use Enum.each with a range.
Enum.each(0..2, fn i ->
IO.puts("range #{i}")
end)
# Elixir doesn't have a direct equivalent to an infinite loop,
# but we can use Stream.repeatedly for a similar effect.
Stream.repeatedly(fn ->
IO.puts("loop")
throw(:break)
end)
|> Enum.take(1)
|> (fn _ -> :ok end).()
# You can also use 'continue' logic in Elixir loops.
Enum.each(0..5, fn n ->
if rem(n, 2) == 0 do
:continue
else
IO.puts(n)
end
end)
end
end
ForExample.run()
This Elixir code demonstrates various looping constructs that are similar to the original example. Here’s a breakdown of the differences and similarities:
Elixir doesn’t have a traditional
for
loop like many imperative languages. Instead, it uses comprehensions andEnum
functions for iteration.The first loop uses a comprehension with
Stream.repeatedly
to mimic a condition-based loop. This is not idiomatic Elixir, but it demonstrates how you could achieve a similar effect.The “classic” loop is replaced with
Enum.each
and a range, which is more idiomatic in Elixir.The range-based loop is also implemented using
Enum.each
.Elixir doesn’t have an exact equivalent to an infinite loop, but we can use
Stream.repeatedly
to create a similar effect. We usethrow
andcatch
to break out of the loop.The last example uses
Enum.each
with a conditional to demonstrate the concept of “continue”.
To run this program, save it as for_example.exs
and use:
$ elixir for_example.exs
1
2
3
0
1
2
range 0
range 1
range 2
loop
1
3
5
Elixir’s functional nature leads to different idioms for iteration compared to imperative languages. The Enum
and Stream
modules provide powerful tools for working with collections and sequences.