tuple
===========================================================================
%% A `tuple` is an ordered collection of elements, potentially of heterogeneous kinds, similar to a fixed-length list.
1. Syntax
-------------------------------------------------------------------------------
Tuples are defined using parentheses `()` with elements separated by commas.
```
(1, true)
("Hello", 42, false)
(1, ("Hello", false))
```
When parsed and rendered, this code will appear as:
```mech:disabled
(1, true) -- two-tuple of f64 and bool
("Hello", 42, false) -- three-tuple of string, f64, and bool
(1, ("Hello", false)) -- nested tuple
```
(!)> There is no such thing as a single-element tuple in Mech. A single value in parentheses is just that value. For example, `(42)` is just `42`, not a one-tuple containing `42`.
2. Kind
-------------------------------------------------------------------------------
The kind of a tuple is determined by the kinds of its elements. For example:
```mech:disabled
(1, true) -- kind: {{<(f64,bool)>}}
("Hello", 42) -- kind: {{<(string,f64)>}}
```
Tuples can be nested, and the kind reflects the structure:
```mech:disabled
(1, ("Hello", false)) -- kind: {{<(f64,(string,bool))>}}
```
3. Construction
-------------------------------------------------------------------------------
There are two ways to construct tuples:
- Tuple literals
- Comprehensions
(3.1) Tuple Literals
```mech:ex 3.1
q := (10, "b", true)
nested := (1, ("Hello", false))
```
(3.2) Comprehensions
Tuples can be constructed using comprehensions:
```mech:ex 3.2
x := {1, 2, 3}
y := {4, 5}
{(a, b) | a <- x, b <- y}
```
The above comprehension generates a set of tuples containing all combinations of elements from sets `x` and `y`.
4. Accessing Elements
-------------------------------------------------------------------------------
Elements can be accessed in two ways:
- Dot access
- Destructuring
(4.1) Dot Access
Tuple elements are accessed by their 1-based index using the `.` operator.
```mech:ex 4.1
q := (10, "b", true)
q.1
```
Similarly:
```mech:ex 4.1
q.2
```
Nested tuples are accessed recursively:
```mech:ex 4.2
nested := (1, ("Hello", false))
nested.2 -- Access the second element, which is a tuple
```
To access elements within the nested tuple:
```mech:ex 4.2
nested.2.1 -- Access "Hello"
```
(4.2) Destructuring
Tuples can be destructured into variables:
```mech:ex 5.1
a := (10, 11, 12)
(x, y, z) := a
x + y + z
```
Destructuring works recursively for nested tuples:
```mech:ex 5.2
nested := (1, ("Hello", false))
(a, (b, c)) := nested
a -- 1
b -- "Hello"
c -- false
```
6. Assigning Elements
----------------------------------------------------------------------------
Mutable tuples allow assignment via dot indexing:
```mech:ex 6.1
~q := (10, "b", true)
q.1 = 42 -- Updates the first element
q
```
Immutable tuples cannot be modified. The following code raises an error:
```mech:disabled
q := (10, "b", true)
q.1 = 42 -- Error: cannot assign to element of immutable tuple
```