Elixir : Basics of Tuple datatype
Tuples are a built-in collection datatype in elixir that are built on top of the erlang type system’s datatype of the same name. Tuples are internally implemented based on the array data structure and can hold ordered heterogeneous elements, stored contiguously in memory. Tuples follow a zero based index and provide a performant(O(1)) index based data access. Accessing the size of the tuple is also a constant time operation since the size is pre-computed and stored as metadata. Modifying a tuple requires making a shallow copy of the original tuple along with the new modifications and this whole operation will take linear time. Tuples are used mainly for fixed size collections that require fast data access while lists are used for variable length collections that require frequent modification and traversal.
Syntax
Tuples can be defined using the curly braces syntax {}
, containing the elements as comma separated values within the curly braces. Tuples are widely used to group related elements and one such example is return values from functions, that are tuples with result atoms and the output values.
{} # empty tuple
{4, 5} # tuple containing 2 elements
{:ok, result} # two common return value tuple structure used in functions
{:error, reason}
Reference modules
The modules Kernel and Tuple contain functions that can operate on a tuple. Since data is immutable in elixir, any function that operates on a tuple will create a new version of the tuple and does not modify any existing structure. The Kernel’s elem/2
guard function can be used to access an element in tuple by index and the tuple_size/1
guard function can be used to get the size of the tuple. The Kernel function put_elem/3
can be used to replace an element at a particular index while the Tuple function insert_at/3
can be used to insert an element at a particular index. Unlike lists, the tuple datatype does not implement the Enumerable protocol and hence the Enum and Stream modules cannot operate on the tuples.
a = {1, 2, 3}
elem(a,0)
1
tuple_size(a)
3
Tuple.to_list(a)
[1, 2, 3]
put_elem(a, 0, :one)
[:one, 2, 3]
Tuple.insert_at(a, 0, :one)
[:one, 1, 2, 3]
If you are curious about the internal data representation of tuples, check out this article.