Elixir

Elixir Recursion Basics

Generally speaking, when mapping over data in Elixir, you want to use the Enum module. However sometimes you might need to do something more powerful; here you can reach for recursion.

The two most common ways that I use recursion are with lists and binary data (strings). I reach for recursion over Enum.map/2 to process each item of the list in a very specific manner. You can see a complex example here in Kalevala, a text game engine, transforming text into tags.

To write a recursive function, you want at minimum two things: a base case, and the recursive case. The base case is where recursion breaks and a value is returned instead of calling itself again. You can see this in the simple example below.

def sum_orders([]), do: 0

def sum_orders([order | orders]) do
  order.total + sum_orders(orders)
end

The sum_orders function will call recursively until its parameters are an empty List. This is determined by pattern matching, which determines which version of sum_orders gets called based on the parameters given to it. As long as there is a list of orders in the arguments, the recursive case will be called. It’s a tidier way of saying “If the orders are not empty, keep adding the totals. If they are empty, stop.”

The final thing to be aware of in Elixir’s recursion, is tail call optimization (TCO). When using recursion, as often as you possibly can, make sure the last thing a function calls is itself. TCO lets you avoid a stack overflow, and is how something like a GenServer can run forever by calling the same function over and over.

Learn more about Tail calls

Header photo by Danny Howe on Unsplash

You've successfully subscribed to SmartLogic Blog
Great! Next, complete checkout for full access to SmartLogic Blog
Welcome back! You've successfully signed in.
Unable to sign you in. Please try again.
Success! Your account is fully activated, you now have access to all content.
Error! Stripe checkout failed.
Success! Your billing info is updated.
Error! Billing info update failed.