Common imperative programming languages provide a loop structure for running a block of code many times? e.g. for loop: pseudo code:
for(i=0;i<256;++i){ expression one; statement one; many code goes here }
The large block of code in the for loop will be executed many times. But as a functional programming langage, Elixir provide no loop. I know Enum module provides many functions for iterating code many times. e.g.
Enum.each(0..99, fn(x) -> IO.puts "hello, world!" end)
The code above will be executed 100 times. Print 100 "hello, world!" But it's just a one-line statement. How to execute a large block of code n times in Elixir? What is the right Elixir way to do so? I'm fresh new to Elixir. Could you guys give me a small sample code for learning? Thank all of you guys so much!
14 Answers
You have a good enough solution right in your question. Enum.each
is one bona fide way to apply a function X number of times.
Maybe if we format it differently, you might see what you can do:
Enum.each(0..99, fn(_x) -> IO.puts "hello, world!" end)
The function is just like any other function, except that it is defined inline.
So, just add more lines of code ...
Enum.each(0..99, fn(x) -> IO.puts "hello, world!" IO.puts x end)
If you want to reference a defined function, you can pass a function signature:
defmodule Test do def bar(x) do IO.puts "hello, world!" IO.puts x end def foo do Enum.each(0..99, &bar/1) end end
1There are many ways of doing it. You can just write your own recursive function or follow other examples mentioned here.
You can also define your "block" of code as a separate function (anonymous or named) and use it in Enum.each
or Enum.map
depending on what exactly needs to be returned.
Or actually use for like this:
for x <- 0..10 do yor_block_of_code end
For lazy iteration one might use Stream.iterate/2
:
1 |> Stream.iterate(& &1+1) |> Stream.each(&IO.puts(&1)) |> Enum.take(99)
This is the general pattern to simulate a for loop in functional code:
defmodule Test do def for_loop(f,counter,upper_limit) do if counter < upper_limit do f.() for_loop(f, counter+1, upper_limit) # Note recursive call here else nil end end end
And you would invoke the call something like this:
Test.for_loop(fn() -> IO.puts "Hello" end,0,100)
Note that I can't be very specific in this code because the behavior of f
in that call will affect some of the coding of the loop itself.
However, that's the general pattern--recursively invoke the function passing a counter that's incremented by 1 on each call.
ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJoa3BtY2iEeX2Om5ysrF2srrp506hkrKGdqrmiwMRmmGaen6d6rbvOqWSipl2auarEyKs%3D