summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@plataformatec.com.br>2017-12-11 12:11:52 +0100
committerJosé Valim <jose.valim@plataformatec.com.br>2017-12-11 12:11:52 +0100
commitd26181a71dfd10bd9162d0b1b54ef11ae67017c7 (patch)
tree2bb65405ec11a9592789f3f798c5123ee7b09d0f
parent840c995af63961355a5a1410ecb1392583902181 (diff)
downloadelixir-d26181a71dfd10bd9162d0b1b54ef11ae67017c7.tar.gz
Improve docs for tuples
-rw-r--r--lib/elixir/lib/tuple.ex66
1 files changed, 43 insertions, 23 deletions
diff --git a/lib/elixir/lib/tuple.ex b/lib/elixir/lib/tuple.ex
index f77a93778..3e487b28a 100644
--- a/lib/elixir/lib/tuple.ex
+++ b/lib/elixir/lib/tuple.ex
@@ -2,18 +2,19 @@ defmodule Tuple do
@moduledoc """
Functions for working with tuples.
- Tuples are ordered collections of elements; tuples can contain elements of any
- type, and a tuple can contain elements of different types. Curly braces can be
- used to create tuples:
+ Tuples are ordered collections of elements. Tuples can contain elements
+ of any type, and a tuple can contain elements of different types. Curly
+ braces can be used to create tuples:
iex> {}
{}
iex> {1, :two, "three"}
{1, :two, "three"}
- Tuples store elements contiguously in memory; this means that accessing a
- tuple element by index (which can be done through the `Kernel.elem/2`
- function) is a constant-time operation:
+ Tuples store elements contiguously in memory. This means accessing a
+ tuple element by index doesn't depend on the number of elements in the
+ tuple. We say the operation is done in constant-time, via the
+ `Kernel.elem/1` function:
iex> tuple = {1, :two, "three"}
iex> elem(tuple, 0)
@@ -21,7 +22,7 @@ defmodule Tuple do
iex> elem(tuple, 2)
"three"
- Same goes for getting the tuple size (via `Kernel.tuple_size/1`):
+ Same goes for getting the tuple size with `Kernel.tuple_size/1`:
iex> tuple_size({})
0
@@ -29,22 +30,41 @@ defmodule Tuple do
3
Tuples being stored contiguously in memory also means that updating a tuple
- (for example replacing an element with `Kernel.put_elem/3`) will make a copy
- of the whole tuple.
-
- Tuples are not meant to be used as a "collection" type (which is also
- suggested by the absence of an implementation of the `Enumerable` protocol for
- tuples): they're mostly meant to be used as a fixed-size container for
- multiple elements. For example, tuples are often used to have functions return
- "enriched" values: a common pattern is for functions to return `{:ok, value}`
- for successful cases and `{:error, reason}` for unsuccessful cases. For
- example, this is exactly what `File.read/1` does: it returns `{:ok, contents}`
- if reading the given file is successful, or `{:error, reason}` otherwise
- (e.g., `{:error, :enoent}` if the file doesn't exist).
-
- This module provides functions to work with tuples; some more functions to
- work with tuples can be found in `Kernel` (`Kernel.tuple_size/1`,
- `Kernel.elem/2`, `Kernel.put_elem/3`, and others).
+ (for example replacing an element with `Kernel.put_elem/3`) will make a
+ shallow copy of the whole tuple. The tuple elements are still shared thanks
+ to immutability.
+
+ Tuples are not meant to be used as a "collection" type but rather as a
+ fixed-size container for multiple elements. That's why it is not possible
+ to traverse a tuple dynamically using the functions in the `Enum` module.
+
+ For example, tuples are often used to have functions return "enriched"
+ values: a common pattern is for functions to return `{:ok, value}` for
+ successful cases and `{:error, reason}` for unsuccessful cases. This is
+ exactly what `File.read/1` does: it returns `{:ok, contents}` if reading
+ the given file is successful, or `{:error, reason}` otherwise, such as
+ when the file does not exist.
+
+ The most common operations performed on tuples are available in `Kernel`
+ (`Kernel.tuple_size/1`, `Kernel.elem/2`, `Kernel.put_elem/3`, and others)
+ and are automatically imported into your code. The functions in this module
+ cover other cases, such as dynamic creation of tuples (`Tuple.duplicate/2`)
+ and conversion to list (`Tuple.to_list/1`). The functions that add and remove
+ elements from tuples, changing their size, are rarely used in practice, as
+ they typically imply tuples are being used as collections. Even if you have
+ a tuple `{:ok, atom}` and you want to append another element to it, such as
+ an empty map, it is preferrable to rely on pattern matching and create a new
+ tuple than manipulating it dynamically:
+
+ tuple = {:ok, :example}
+
+ # Avoid
+ Tuple.insert_at(tuple, 2, %{}}
+
+ # Prefer
+ {:ok, atom} = tuple
+ {:ok, atom, %{}}
+
"""
@doc """