elixir

Is it idiomatic to use guards when you only have one definition of a function in Elixir?


Is it idiomatic to use guards when you only have one definition of a function?

eg.

defmodule Math do
  def add(a, b) when is_integer(a) and is_integer(b) do
    a + b
  end
end

or

defmodule Math do
  def add(a, b) do
    a + b
  end
end

Which is preferred?


Solution

  • One of the main benefits of guards and pattern-matching in general is to fail early (part of the famous "let it crash" philosophy of erlang/elixir) and to completely prevent the underneath logic to being called at all if inputs do not match your assumptions.

    While your add example doesn't really need it in the first place, a less trivial function doing actual business logic (say a public function from a phoenix context) could benefit from guards / more restrictive patterns. If it were to be called with invalid data, it might be:

    • harder to debug when it fails deeper in a nested call
    • unpredictable and potentially dangerous when it doesn't fail

    Of course, guards can only check superficially and detect some obvious errors, they do not replace validating untrusted user input (e.g. with ecto).

    This section about guards and invalid data describes it nicely. It is from a guide to write libraries on Hex, but it specifically states that this philosophy also applies to regular Elixir code.