How to format return values

I have searched, but I have not found it. If it is a duplicated question I am so sorry.

I want to know how and when to format the returned values in a function. Because a lot of times, it is returned {:ok, value} and others just value . So, when should I use the status along the value?

1 Like

From laziness we treat value as {:ok, value} but if value is an error code then it should be {:error, value}.

A status should be descriptive and makes sense for the callee when pattern matching.

E.g. if a function spec is
{:ok, :connected} | {:ok, :received} | {:error, error_code} it can easily be changed to :connected | :received | {:error, error_code} without losing information.

1 Like

Often functions ending with ! will return the value, or raise an error.

While those without ! at the end return {:ok, value} | {:error, reason}

2 Likes

Currently, I am working on a project. I will use it as an example to explain my point.

There is a function that returns a list if you pass a struct. And a second function that creates a struct if you pass a string. However the second function’s string parameter, must have a specific format, otherwise it fails.
So, the return formats I use for each function are:

  1. struct
  2. {:ok, struct} or {:error, reason}

Is it a good choice?

I’d say #2 is the good choice since it’s much more idiomatic and found throughout the ecosystem for functions that can fail. And as @kokolegorille said earlier naming the function with a bang (i.e. func!()) if the function raises instead of returning an error tuple.

That said occasionally I find something like Integer.parse/2 in the stdlib can return {42, ""} or :error. Or Repo.get/3 from Ecto which returns %Struct{...} or nil if the query returns 0 rows. I guess the idea if there are no records it is not an error condition and should return the concept of nothing which is nil or [] for a list of nothing.

1 Like

For your first function it takes a struct and returns a list() :upside_down_face: but yes I do understand what you mean. What happens when it is given an empty list ? Will the function fail or do you expect passing back error codes ?

The first function receives an struct and returns a list() as you said. So, it is never “given a list”, and it is hard (almost impossible to fail?).
So, I just return the list() without any status (:ok, :error).

However, the second function receives a string and returns a struct. But this can fail or do receive wrong values. That is why, the second function returns a status along with the struct.

1 Like