darshandzend
darshandzend

Reputation: 394

Elixir: Tail-call optimized recursion inside conditionals

Will my function below be tail-call optimized in Elixir?

def poller(func, args, interval) do
  case apply(func, args) do
    :done -> :done
    :try_again ->
      :timer.sleep(interval)
      poller(func, args, interval)
  end
end

From what I've read in beginner literature, the optimization applies only when the recursive call is the "very last thing" the function does.

How does this work inside other conditionals? e.g. What if my recursion call is the last thing inside an if, but there's an else block after?

Upvotes: 3

Views: 417

Answers (1)

sabiwara
sabiwara

Reputation: 3159

Yes, your example is valid tail recursion. Using tail recursion with conditionals is actually a very common pattern, it is even necessary in most cases except if you want an infinite loop.

Here is an example from the standard library (List.zip/1).

Here is another one (List.pop_at/3): note there is no case expression, but multiple clause functions are actually translated as case during compilation to core erlang. This is actually the same thing.

if or cond are the same, since they are translated as case as well. The important point is that the recursive call can only be called as the last thing of each conditional branch.

Upvotes: 3

Related Questions