Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tuple Passover #2 #990

Merged
merged 3 commits into from
Apr 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 29 additions & 14 deletions src/expressions/tuple-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@
> _TupleElements_ :\
> &nbsp;&nbsp; ( [_Expression_] `,` )<sup>+</sup> [_Expression_]<sup>?</sup>

Tuple expressions evaluate into [tuple values][tuple type] with the operands initializing the elements of the tuple.
A *tuple expression* constructs [tuple values][tuple type].

Tuple expressions are written by listing the [operands] in a parenthesized, comma-separated list. 1-ary tuple expressions require a comma after their operand to be disambiguated with a [parenthetical expression].
The syntax for tuple expressions is a parenthesized, comma separated list of expressions, called the *tuple initializer operands*.
1-ary tuple expressions require a comma after their tuple initializer operand to be disambiguated with a [parenthetical expression].

The number of operands is the arity of the constructed tuple.
Tuple expressions without operands produce the unit tuple.
For other tuple expressions, the first written operand initializes the 0th element and subsequent operands initializes the next highest element.
For example, in the tuple expression `('a', 'b', 'c')`, `'a'` initializes the value of the 0th element, `'b'` the 1st, and `'c'` the 2nd.
Tuple expressions are a [value expression] that evaluate into a newly constructed value of a tuple type.
The number of tuple initializer operands is the arity of the constructed tuple.
Tuple expressions without any tuple initializer operands produce the unit tuple.
For other tuple expressions, the first written tuple initializer operand initializes the field `0` and subsequent operands initializes the next highest field.
For example, in the tuple expression `('a', 'b', 'c')`, `'a'` initializes the value of the field `0`, `'b'` field `1`, and `'c'` field `2`.

Examples of tuple expressions:
Examples of tuple expressions and their types:

| Expression | Type |
| -------------------- | ------------ |
Expand All @@ -37,19 +39,26 @@ Examples of tuple expressions:
> _TupleIndexingExpression_ :\
> &nbsp;&nbsp; [_Expression_] `.` [TUPLE_INDEX]

Tuple indexing expressions evaluate like [field access expressions], but access elements of [tuples][tuple type] or [tuple structs].
A *tuple indexing expression* accesses fields of [tuples][tuple type] and [tuple structs][tuple struct].

Tuple index expressions are written as an operand, `.`, and a tuple index.
The index must be written as a [decimal literal] with no leading zeros, underscores, or suffix.
The operand must have the type of a tuple or tuple struct.
If the tuple index is not an element of the tuple or tuple struct, it is a compiler error.
The syntax for a tuple index expression is an expression, called the *tuple operand*, then a `.`, then finally a tuple index.
The syntax for the *tuple index* is a [decimal literal] with no leading zeros, underscores, or suffix.
For example `0` and `2` are valid tuple indices but not `01`, `0_`, nor `0i32`.

The type of the tuple operand must be a [tuple type] or a [tuple struct].
The tuple index must be a name of a field of the type of the tuple operand.

Evaluation of tuple index expressions has no side effects beyond evaluation of its tuple operand.
As a [place expression], it evaluates to the location of the field of the tuple operand with the same name as the tuple index.

Examples of tuple indexing expressions:

```rust
// Indexing a tuple
let pair = ("a string", 2);
assert_eq!(pair.1, 2);

// Indexing a tuple struct
# struct Point(f32, f32);
let point = Point(1.0, 0.0);
assert_eq!(point.0, 1.0);
Expand All @@ -58,15 +67,21 @@ assert_eq!(point.1, 0.0);

> **Note**: Unlike field access expressions, tuple index expressions can be the function operand of a [call expression] as it cannot be confused with a method call since method names cannot be numbers.

> **Note**: Although arrays and slices also have elements, you must use an [array or slice indexing expression] or a [slice pattern] to access their elements.

[_Expression_]: ../expressions.md
[_InnerAttribute_]: ../attributes.md
[array or slice indexing expression]: array-expr.md#array-and-slice-indexing-expressions
[attributes on block expressions]: block-expr.md#attributes-on-block-expressions
[call expression]: ./call-expr.md
[decimal literal]: ../tokens.md#integer-literals
[field access expressions]: ./field-expr.html#field-access-expressions
[Inner attributes]: ../attributes.md
[inner attributes]: ../attributes.md
[operands]: ../expressions.md
[parenthetical expression]: grouped-expr.md
[place expression]: ../expressions.md#place-expressions-and-value-expressions
[slice pattern]: ../patterns.md#slice-patterns
[tuple type]: ../types/tuple.md
[tuple structs]: ../types/struct.md
[tuple struct]: ../types/struct.md
[TUPLE_INDEX]: ../tokens.md#tuple-index
[value expression]: ../expressions.md#place-expressions-and-value-expressions
41 changes: 20 additions & 21 deletions src/types/tuple.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@
> &nbsp;&nbsp; &nbsp;&nbsp; `(` `)`\
> &nbsp;&nbsp; | `(` ( [_Type_] `,` )<sup>+</sup> [_Type_]<sup>?</sup> `)`

The *tuple type* is a structural type[^1] for heterogeneous lists of other
types. Each entry in the list is an *element*[^2] of the tuple. The position of
the element makes it the *nth element* using zero (`0`) as the initial index.
*Tuple types* are a family of structural types[^1] for heterogeneous lists of other types.

The number of elements determines the arity of the tuple. A tuple with `n`
elements is called an `n-ary tuple`. For example, a tuple with 2 elements is a
2-ary tuple.
The syntax for a tuple type is a parenthesized, comma-separated list of types.
1-ary tuples require a comma after their element type to be disambiguated with a [parenthesized type].

For convenience and historical reasons, the tuple type with no elements (`()`)
is often called *unit* or *the unit type*. It's one value is also called *unit*
or *the unit value*.
A tuple type has a number of fields equal to the length of the list of types.
This number of fields determines the *arity* of the tuple.
A tuple with `n` fields is called an *n-ary tuple*.
For example, a tuple with 2 fields is a 2-ary tuple.

Tuple types are written by listing the types of their elements in a
parenthesized, comma-separated list. 1-ary tuples require a comma after their
element type to be disambiguated with a [parenthesized type].
Fields of tuples are named using increasing numeric names matching their position in the list of types.
The first field is `0`.
The second field is `1`.
And so on.
The type of each field is the type of the same position in the tuple's list of types.

For convenience and historical reasons, the tuple type with no fields (`()`) is often called *unit* or *the unit type*.
It's one value is also called *unit* or *the unit value*.

Some examples of tuple types:

Expand All @@ -29,16 +32,12 @@ Some examples of tuple types:
* `(i32, String)` (different type from the previous example)
* `(i32, f64, Vec<String>, Option<bool>)`

Values of this type are constructed using a [tuple expression]. Furthermore,
various expressions will produce the unit value if there is no other meaningful
value for it to evaluate to. Tuple elements can be accessed by either a [tuple
index expression] or [pattern matching].

[^1]: Structural types are always equivalent if their internal types are
equivalent. For a nominal version of tuples, see [tuple structs].
Values of this type are constructed using a [tuple expression].
Furthermore, various expressions will produce the unit value if there is no other meaningful value for it to evaluate to.
Tuple fields can be accessed by either a [tuple index expression] or [pattern matching].

[^2]: Element is equivalent to field, except numerical indexes instead of
identifiers
[^1]: Structural types are always equivalent if their internal types are equivalent.
For a nominal version of tuples, see [tuple structs].

[_Type_]: ../types.md#type-expressions
[parenthesized type]: ../types.md#parenthesized-types
Expand Down