# Elixir Recursion

Note: this page has been created with the use of AI. Please take caution, and note that the content of this page does not necessarily reflect the opinion of Cratecode.

Recursion is a powerful technique in programming that involves a function calling itself to solve a problem. This concept is prevalent in functional programming languages like Elixir. By breaking a problem down into smaller parts, recursion can efficiently tackle complex tasks with elegance and simplicity.

## Recursive Functions in Elixir

In Elixir, you can create a recursive function by defining a function that calls itself within its body. To avoid infinite loops, you'll need to establish a base case, which is a condition where the function stops calling itself and returns a result.

Let's start with a classic example: calculating the factorial of a number. The factorial of a number n is the product of all positive integers up to n. We can define this recursively as `n! = n * (n-1)!` for n > 0 and `0! = 1`.

Here's how we can implement a factorial function in Elixir using recursion:

``````defmodule Factorial do
def of(0), do: 1
def of(n) when n > 0 do
n * of(n - 1)
end
end``````

In this example, we define a module `Factorial` with a recursive function `of/1`. The base case is defined for `n = 0`, returning 1. For other positive integers, the function calls itself with `n - 1` as its argument and multiplies the result by `n`.

## Handling Recursive Function Calls

One potential issue with recursion is the increase in memory consumption due to recursive function calls. This can lead to a stack overflow if the recursion goes too deep. To avoid this, Elixir supports tail call optimization (TCO), which eliminates the need for additional memory allocation in specific cases.

For TCO to work, the last operation in the function must be the recursive function call. Here's an example of a tail-recursive function for calculating the sum of a list of numbers:

``````defmodule ListSum do
def calc(list), do: calc(list, 0)

defp calc([], acc), do: acc
defp calc([head | tail], acc) do
calc(tail, acc + head)
end
end``````

In this example, we use an accumulator (`acc`) to keep track of the sum. The helper function `calc/2` is tail-recursive because the last operation is the recursive call to itself with an updated accumulator. This allows Elixir to optimize the function and prevent stack overflow.

## Some Practical Examples

Recursion is not only limited to mathematical operations. You can use it to solve various problems, such as traversing data structures or generating permutations.

Here's an example of using recursion to reverse a list in Elixir:

``````defmodule ReverseList do
def reverse(list), do: reverse(list, [])

defp reverse([], acc), do: acc
defp reverse([head | tail], acc) do
reverse(tail, [head | acc])
end
end``````

In this example, we use an accumulator to store the reversed list. The private function `reverse/2` takes the first element from the input list and appends it to the accumulator. This process continues until the input list is empty, at which point the function returns the reversed list.

Recursion in Elixir unleashes the potential of functional programming and can lead to elegant solutions for complex problems. By understanding how to create recursive functions and optimize them using tail call optimization, you can write efficient and maintainable code in Elixir.

Hey there! Want to learn more? Cratecode is an online learning platform that lets you forge your own path. Click here to check out a lesson: Recursion Intro (psst, it's free!).