Coming from an object oriented language with data mutability, learning looping in Elixir required that I let go of my current understanding about iterating over a collection. In fact, just forget looping and think recursion. So, what’s recursion?
Recursion is solving a problem whereby one applies the same solution to smaller instances of that problem. Think, a function calling itself. So, here is what it looks like in Elixir:
defmodule Recursionism do
def operate_on_list_items([], _) do
[]
end
def operate_on_list_itmes([head | tail], fun) do
[fun.(head) | operate_on_list_items(tail, fun)]
end
end
Recursionism.operate_on_list_items([1, 2, 3], fn(n) -> n * n end)
Let’s break this down:
- First we define a multi-clause function called
Recusionism.operate_on_list/2. Multi-cause functions are multiple functions of the same name and arity that are executed depending on the matching of the arguments. - Then, when we call
Recusionism.operate_on_list_items([1, 2, 3], fn(n) -> n * n end), it matches the second multi-clause function definition and executes it. - That second function, uses the anonymous function (it’s second argument) to operate on the first item in the list (
head). The result of applying the anonymous function (fun.(head)) becomes the first item in a new list. - In order to complete the list, the
operate_on_list_itemsfunction calls itself by passing all the remaining items in the original list (tail) as the first argument, along with the same anonymous function as the second argument. - When there are no more items in the list, calling
operate_on_list_itemsmatches the first multi-clause function definition and returns an empty list, thereby stopping the recursion. - The end result is building a list by doing
[1 | [4 | [9 | []]]], which evaluates to[1, 4, 9]
