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?
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.
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:
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.
For your first function it takes a struct and returns a list() 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.