For the last several years, I have participated in Advent of Code, going back and forth between using languages I use day-to-day (Elixir, Ruby) and trying languages I am not as familiar with.

One year, I decided to try using Go. Among other interesting features is the capability of functions to return multiple values, rather than a single value.

For example:

    val, err := strconv.Atoi(s)
In the above line of code, we want to turn a string value s into an integer value val. But, since not all strings can be successfully converted, the function can also return an error. It’s up to us to do someting (or not) with the error, like this:
    val, err := strconv.Atoi(s)

	if err == nil {
		// no error, so we'll do something with val
	} else {
		// we have an error; do things to handle it

Elixir has a similar pattern, using tuples containing :ok or :error as the first value of the tuple. When used with a case statement, a similar flow in Elixir would look like this:

    case string_to_integer(s) do
        {:ok, val} -> # the function succeeded, so do things with val
        {:error, error} -> # the function failed, so handle the error

As I mentioned above, most of my daily work involves Elixir, Ruby, or both. Every so often, I encounter a situation in one language where the “best” or “cleanest” (to me) solution would be something that exists in the other language. At the time I was working Advent of Code problems with Go, I encountered a problem in a Ruby codebase where I wanted to use Elixir’s :ok/:error tuples, but my little bit of Go reminded me of a similar capability in Ruby.

It’s not common, as far as I’ve seen, but it’s perfectly acceptable to write a method like this:

    def do_the_thing(x)
        # Use x to do stuff that may fail,
        # but we don't want to produce an exception
        return result, error
Then we can use the method like this:
    result, error = do_the_thing(s)

    if error 
        # Handle the error
        # Handle the successful result
You do have to be careful that exactly one of either result or error can be null if you’re doing this, or else you may miss something, depending on how you want to handle the returned values.