Multiple guards in Elixir

Literally even!

Something like this:

def blah(a) when a<0, do: 0
def blah(1), do: 1
def blah(a) when a>0, do: 2

Quite literally compiles ‘almost’ identically to (‘almost’ meaning it is more lambda’ish internally):

def blah(a) do
  case a do
    a when a<0 -> 0
    1 -> 1
    a when a>0 -> 2
    _ -> raise %MatchError{...}
  end
end

Actually it compiles into a simple dispatch tree. It’s not like ‘way’ smart in that it can combine all parts possible, but it is pretty decent. In general you can think of it as ‘testing’ the first branch, if that fails it tests the second, if that fails it tests the third, and so on. It is a linear slowdown with the number of cases (though linear more in C terms so it is still blazing fast compared to anything you could write explicitly, this is also why guard calls are restricted).

Precisely. Multiple when’s compiles to different branches in the dispatch tree, where or’s get compiled into the same dispatch branch.

3 Likes