looping in Elixir
Elixir is a functional langauge, “for” and “while” loops don’t really exist.
Examine a for loop in JavaScript:
function lameLoopingCountdown (times) {
for (var i = times; i > 0; i = i - 1 ){
console.log(i)
}
console.log("boom")
}
This loop makes two assumptions about mutability:
-
i is mutable The loop ends when it is no longer true that i > 0. This assumes that i is currently greater than 0, and it will not be greater than 0 at some point in the future. Otherwise, the loop would go on forever.
-
i is mutable i is being decremented by 1 every time around the loop. This is of course only possible if i is mutable.
Okay it really assumed one thing, but in two ways.
How then shall we loop? recursion
defmodule BeginnersRecursion do
def radRecursiveCountdown(times) do
if times <= 0 do #base case, or middle chunk of for loop head, end of loop
IO.inspect "boom"
else
IO.inspect(times) # operation, or body of for loop
radRecursiveCountdown(times - 1) # the mechanism of looping
end
end
end
JavaScript can do the above, but Elixir offers a nice way to clean up recursion with multiple function heads.
defmodule BeginnersRecursion do
def radRecursiveCountdown(0) do
IO.inspect "boom" # base case, end of loop
end
def radRecursiveCountdown(times) do
IO.inspect(times) # operation, or body of for loop
radRecursiveCountdown(times - 1) # the mechanism of looping
end
end
TLDR, To transform a loop into a multi-headed recursive Elixir function:
- extract termination condition of loop into a function head that executes your base case ( i.e. what happens when i is no longer > 0 )
- create another function head to perform the body of the loop
- end the body of the loop with a recursive call, passing the result of the incrementing operation ( i.e. i - 1 ) as the argument.