Here are a few key points about the tuple data type.

  • A tuple is a collection type. It is a structure that contains a fixed number of things.
  • A tuple’s elements are ordered and fixed in size.
  • A tuple does NOT mean TWO. Tuples can have many elements. However, it is common to see a tuple with only two elements. 
  • A common usage in Elixir is to return multiple result values from a function in a tuple.

The following example represents common function return values. Each tuple contains 2 pieces of information or data.

{:ok, result}
{:error, reason}

The first piece of information is an atom (ie: :ok or :error) that tells if the operation succeeded or not. If we got an :ok, we know it succeeded and the next piece of data is the result of the operation. If we got the atom :error then we know the operation failed and the reason may tell us why.

Another example of using a tuple to return multiple pieces of information at once might be the result of a function that splits a list of integers into odd and even sets. Imagine that a function named split_odd_even/1 is available to us. This function leaves the original list unmodified (immutable) and returns the two different result sets through a tuple. It could look like this:

{odd_results, even_results} = split_odd_even([1, 2, 7, 12, 15])

#=> [1, 7, 15]

#=> [2, 12]

Here is another tuple example that contains multiple pieces of data. In this example the tuple contains a person’s name and age:

{"Howard", 32}

Using the Kernel.elem/2 function, you can extract the value of an element from a tuple.

tuple = {:foo, :bar, 3}
elem(tuple, 1)
#=> :bar

elem({:foo, :bar}, 2)
#=> ** (ArgumentError) argument error

A cleaner and more natural way to do this is with “pattern matching” which isn’t covered here.

You can replace an element using Kernel.put_elem/3. Remember, Elixir isn’t changing the tuple, internally it is creating a new tuple where the elements point back to the previous tuple’s values, with the exception of the new change.

tuple = {:foo, :bar, 3}
put_elem(tuple, 2, :baz)
#=> {:foo, :bar, :baz}

You can see that the original tuple variable has not been modified:

#=> {:foo, :bar, 3}

Tuples are best for a fixed number of elements. If you need a dynamic container that preserves order, use a List instead.

1 Comment

  1. Maksym Kosenko on October 6, 2021 at 2:26 pm


Leave a Comment

You must be logged in to post a comment.