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:
1. 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.
2. i is mutable
i is being decremented by 1 every time around the loop. This is of course only possible if i is mutable. 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:
1. Extract termination condition of loop into a function head that executes your base case
( i.e. what happens when i is no longer > 0 )
2. Create another function head to perform the body of the loop
3. End the body of the loop with a recursive call, passing the result of the incrementing operation ( i.e. i – 1 ) as the argument.