# Refactor very remedial recursive loops using pattern matching

I want to know how you would rewrite these two recursive functions using pattern matching, if at all. I’m trying to learn to “think” in Elixir

Simple loop 1

``````defmodule App do
def loop(count) do
IO.inspect count
if(count > 0 ) do
App.loop(count - 1)
end
end
end

App.loop(5)
``````

Simple loop 2

``````defmodule App do
def loopList(list) do
IO.inspect list
if(length(list) <= 0) do
nil
else

App.loopList(tail)
end
end
end

App.loopList([5, 4, 3, 2, 1])``````
1 Like

Hey, I just wrote this quick sketch. Didn’t test it, but it’s just meant to show you that when dealing with recursion, the most idiomatic and common way is to use several function heads to specify the different cases.

In this situation we’ve got two cases, when the count reaches zero and when the count still hasn’t reached zero. So we write a function head for each one, thus separating their logic (which benefits us for debugging and readability) and leverages the possibilities and benefits for pattern matching:

``````defmodule App do
def loop(0), do: :ok
def loop(count) do
loop(count - 1)
end
end
``````

EDIT: in your second example you’re pretty much splitting the different cases but you’re doing everything in the same function. Try to split the different cases in function heads and post the code back and I’ll check it for you if you want!

2 Likes

loop 1:

``````def loop(0), do: #noop
def loop(n) do
IO.inspect(n)
loop(n - 1)
end
``````

loop 2:

``````def loop_list([]), do: #noop
def loop_list(list = [_head | tail]) do
IO.inspect list
loop_list(tail)
end
``````

At least that’s how I’d do it, hope no errors snuck in

edit: As a more general concept that is, pattern match on the termination case as it is often concrete (empty list, 0, 1 etc.) and do the rest in another function definition.

4 Likes

To avoid an infinite loop on `loop(-1)`, I’d add some guard:

``````def loop(0), do: #noop
def loop(n) when n > 0 do
IO.inspect(n)
loop(n - 1)
end
``````
3 Likes