# Tuples

Tuples are heterogeneous, fixed-size, collections of values. Tuples contain 0 to
`N` values, where `N` is unbounded. Tuples are similar to [Records](records.md),
but records have named parameters.

## Syntax

```
let x := #()
let y := #("foo")
let z := #("foo", 1)
let w := #("foo", 1, true, 3.14)
```

## Type of a Standard Tuple

Consider the tuple `("foo", 1, true, 3.14)`. It has type
`(String, Int32, Boolean, Float64)`.

## The Empty Tuple

The type `()` has a single possible value, `()`. This is the empty tuple. It is
typically used as a token to indicate side-effects with no other useful output.

## Maximum Tuple Size

The largest tuple is of size `uint32_max` (a constant value).

## Accessing Tuple Members

Each tuple member is _indexed_ and can be directly accessed via a property of
that index:

```
let w := ("foo", 1, true)
let x := w._1
let y := w._2
let z := w._3
```

## Destructuring Tuples

Tuples can be _destructured_ via [pattern matching](pattern-matching.md)
capabilities. This can take two possible forms.

### Destructured Binding

Tuples may be destructured at the point of binding.

```
let w := ("foo", 1, true)
let (x, y, z) := w
```

### Destructured Match Case

```
let w := ("foo", 1, true)

let z :=
    match w
        case ("foo", _, x) => x
        case _ => false
    end match
```

## Metadata

`size`: Type `UInt32`, denotes the tuple size.

```
let x: (Int32, Int32, Int32) := (1, 2, 3)
let y: UInt32 := @x.size
```