# Recursion in elixir

## September 21, 2017 elixirrecursion

I am new to elixir, and I find this interesting at the time of writing, I am coming from NodeJs :)

The major ingredients of recursion are: - An exercise to perform repeatedly, - A condition to break off the repeated exercise

Lets say we want to write a function that will return building identifiers where restaurants have not yet closed. The first argument is the current hour as integer, the second argument is the current minute as integer, the third argument is the list of restaurants containing; the name of the canteen, building identifier, closing hour, closing minute.

``````mix new restaurant
``````
``````# ~/restaurant/lib/restaurant.ex

defmodule Restaurant do
defstruct name: nil, id: nil, closing_hour: nil, closing_minute: nil

def get_opened(hour, minute, restaurants) do
check_if_opened(hour, minute, restaurants, [])
end

defp check_if_opened(hour, minute, [restaurant = %Restaurant{closing_hour: c_hour, closing_minute: c_minute} | tail], accumulator)
do
case (c_hour >= hour) do
true when (c_hour != hour) -> check_if_opened(hour, minute, tail, (accumulator ++ [restaurant]))
true when (c_hour == hour) -> fn  ->
case (minute < c_minute) do
true -> check_if_opened(hour, minute, tail, (accumulator ++ [restaurant]))
false -> check_if_opened(hour, minute, tail, accumulator)
end
end.()
false -> check_if_opened(hour, minute, tail, accumulator)
end
end
defp check_if_opened(_, _, [], acummulator) do
acummulator
end
end
``````

#### Explanation

`get_opened\3` is the public function that is called, and this is given the parameters described earlier, the hour, minute and the list of restaurants we want to check recursively using the `check_if_opened\4` function. There are two `check_if_opened\4` functions, thanks to the magic of elixir, this is pattern matching at work. When `check_if_opened\4` is called it will only match one based on the parameters defined on the function.

In our case we have `check_if_opend\4` which is targeting an empty restaurant list and another one which will match a non empty list. Which is our golden plan of breaking off from the recursion.

This comes to mind when looking at this solution “An Enum method could have been used to operate on the restaurant list”, yes, this is possible but the objective of this snippet is to demonstrate the explicit filtering of the restaurants in order to showcase recursion in elixir.

Let’s test our restaurant module:

``````#~/restaurant/test/restaurant_test.exs
defmodule RestaurantTest do
use ExUnit.Case

setup_all do
restaurants_list = [
%Restaurant{name: "Kohvic center", id: "KHV", closing_hour: 16, closing_minute: 30},
%Restaurant{name: "Kohvic center2", id: "KHV2", closing_hour: 14, closing_minute: 00},
%Restaurant{name: "Liivi 2 Restaurant", id: "Liivi-2", closing_hour: 19, closing_minute: 45},
]
{:ok, [restaurants: restaurants_list]}
end

test "check available restaurants for 16:46", %{restaurants: restaurants} do
assert [%Restaurant{id: "Liivi-2"}] = Restaurant.get_opened(16, 46, restaurants) #One restaturant should be opened
end

test "check available restaurants for 18:46", %{restaurants: restaurants} do
assert 0 = length(Restaurant.get_opened(19, 46, restaurants)) #All restaurants should be closed for this time
end

test "check available restaurants for 13:00", %{restaurants: restaurants} do
assert 3 = length(Restaurant.get_opened(13, 00, restaurants)) #All restaurants should be opened by this time
end
``````