Result tuples and "with" statements. Any best practice?

Hi folks,

I’m playing around with a Phoenix based project and have a question about public functions and the results.

I like how it’s possible to use the with statements to chain together different conditions. But it is not so nice if my functions just return 1 value. Then the pattern matching is not so good.

So I guess the question is - should I aim for that most of the public functions always return a tuple with :ok and :error? Is there any best practice?

with/2 is an expression, as everything else in elixir as well.

Besides of that, I’m not really sure. Sometimes returning results makes sense, sometimes not. As well as sometimes usage of with/2 makes sense and sometimes not, as well as sometimes pipes makes sense…

If the operation in question can’t fail, I’m not sure why one should use a tupled version. If it always returns {:ok, a}, then the :ok becomes meaningless. Its fine to just return a then.

So with this theory in mind, I assume that non-tagged return values are always a success and I’m wondering what you want to match on at all.

Besides of that, an idiom has evelved around this to be able to recognize the place of failure, perhaps its that what you are looking for?

with {:even, n} when mod(n, 2) == 0 <- {:even, Enum.rand(1..10)} do
  n
else
  {:even, n} -> 2 * n
end
2 Likes

There‘s also the case where the function itself does not know if a result is a „success“ or not. Take e.g. common changeset/2 functions: They just create the changeset and do validations, but if failed validations are a problem and how to handle them is usually up to the caller to decide.

3 Likes