ðŸŠąList and tuples


Lists in Elixir are implemented as linked lists and are denoted using square brackets:

iex(1)> x = [1, 2, 3, 4]
[1, 2, 3, 4]

Since Elixir is dynamically typed, you can create lists of different types that will, by default, be treated as the an [any()] type.

iex(2)> x = ["hi", 1, true, :atom]
["hi", 1, true, :atom]

Common list operations

List concatenation is achieved using ++/2 and list subtraction is achieved using --/2.

iex(3)> [1, 2] ++ [4, 5]
[1, 2, 4, 5]
iex(4)> [1, 2, 3] -- [2, 3]

There are other built-in functions like hd/1 and tl/1 that return the head and remainder of the linked list (excluding the head) respectively. You can also use length/1 to retrieve the length of the list.

iex(5)> hd([1, 2, 3])
iex(6)> tl([1, 2, 3])
[2, 3]
iex(7)> hd([])
** (ArgumentError) errors were found at the given arguments:

  * 1st argument: not a nonempty list

    iex:7: (file)


Tuples, on the other than, use curly braces instead:

iex(7)> t = {:ok, "hello", 1}
{:ok, "hello", 1}

Use the tuple_size/1 function to retrieve the length of the tuple and elem/2 to retrieve an element of the tuple given its zero-based index.

iex(8)> elem(t, 2)
iex(9)> elem(t, 1)
iex(10)> tuple_size(t)

Tuples, unlike arrays, are of fixed size. So the size of the tuple cannot be changed (i.e. cannot add to an existing tuple).

Lists or tuples?

Both lists and tuples are immutable data structures so any operations on an existing list/tuple will result in a new list/tuple being created.

However, lists are represented as linked lists. Thus, any operation that will require searching through a linked list will always take O(n)O(n) time where nn is the length of the list.

Tuples, on the other hand, are much closer to arrays in representation: being stored contiguously in memory. Thus, most tuple operations are quick, such as getting by index. However, operations that require updating the tuple can be more costly as a new contiguous memory must be located to be assigned.

Elixir has some compiler-level optimizations to reduce the overall memory usage by tuples. For instance, when modifying a tuple, the existing elements are shared between the old and new tuple.

Tuples are more commonly used as return values with fixed sizes, such as {:ok, value} and {:error, error}.

Comparing lists and tuples

The equality operators, == and != both work on lists and tuples as well.

Last updated