diff --git a/src/expressions/tuple-expr.md b/src/expressions/tuple-expr.md index ef0576113..e9b1654c2 100644 --- a/src/expressions/tuple-expr.md +++ b/src/expressions/tuple-expr.md @@ -9,16 +9,18 @@ > _TupleElements_ :\ >    ( [_Expression_] `,` )+ [_Expression_]? -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 | | -------------------- | ------------ | @@ -37,19 +39,26 @@ Examples of tuple expressions: > _TupleIndexingExpression_ :\ >    [_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); @@ -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 diff --git a/src/types/tuple.md b/src/types/tuple.md index bfef43053..3877a2672 100644 --- a/src/types/tuple.md +++ b/src/types/tuple.md @@ -5,21 +5,24 @@ >       `(` `)`\ >    | `(` ( [_Type_] `,` )+ [_Type_]? `)` -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: @@ -29,16 +32,12 @@ Some examples of tuple types: * `(i32, String)` (different type from the previous example) * `(i32, f64, Vec, Option)` -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