Skip to content

Commit 6263944

Browse files
committed
Update reference docs
1 parent 87cdbc8 commit 6263944

File tree

2 files changed

+75
-73
lines changed

2 files changed

+75
-73
lines changed

docs/_docs/reference/experimental/named-tuples.md renamed to docs/_docs/reference/other-new-features/named-tuples.md

Lines changed: 74 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
---
22
layout: doc-page
33
title: "Named Tuples"
4-
nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/named-tuples.html
4+
nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/named-tuples.html
55
---
66

7-
The elements of a tuple can now be named. Example:
7+
Starting in Scala 3.6, the elements of a tuple can be named. Example:
88
```scala
99
type Person = (name: String, age: Int)
1010
val Bob: Person = (name = "Bob", age = 33)
@@ -94,6 +94,24 @@ Bob match
9494
case (age = x, name = y) => ...
9595
```
9696

97+
### Pattern Matching with Named Fields in General
98+
99+
We allow named patterns not just for named tuples but also for case classes. For instance:
100+
```scala
101+
city match
102+
case c @ City(name = "London") => println(p.population)
103+
case City(name = n, zip = 1026, population = pop) => println(pop)
104+
```
105+
106+
Named constructor patterns are analogous to named tuple patterns. In both cases
107+
108+
- every name must match the name some field of the selector,
109+
- names can come in any order,
110+
- not all fields of the selector need to be matched.
111+
112+
Named patterns are compatible with extensible pattern matching simply because
113+
`unapply` results can be named tuples.
114+
97115
### Expansion
98116

99117
Named tuples are in essence just a convenient syntax for regular tuples. In the internal representation, a named tuple type is represented at compile time as a pair of two tuples. One tuple contains the names as literal constant string types, the other contains the element types. The runtime representation of a named tuples consists of just the element values, whereas the names are forgotten. This is achieved by declaring `NamedTuple`
@@ -119,6 +137,47 @@ The translation of named tuples to instances of `NamedTuple` is fixed by the spe
119137
- All tuple operations also work with named tuples "out of the box".
120138
- Macro libraries can rely on this expansion.
121139

140+
### Computed Field Names
141+
142+
The `Selectable` trait now has a `Fields` type member that can be instantiated
143+
to a named tuple.
144+
145+
```scala
146+
trait Selectable:
147+
type Fields <: NamedTuple.AnyNamedTuple
148+
```
149+
150+
If `Fields` is instantiated in a subclass of `Selectable` to some named tuple type,
151+
then the available fields and their types will be defined by that type. Assume `n: T`
152+
is an element of the `Fields` type in some class `C` that implements `Selectable`,
153+
that `c: C`, and that `n` is not otherwise legal as a name of a selection on `c`.
154+
Then `c.n` is a legal selection, which expands to `c.selectDynamic("n").asInstanceOf[T]`.
155+
156+
It is the task of the implementation of `selectDynamic` in `C` to ensure that its
157+
computed result conforms to the predicted type `T`
158+
159+
As an example, assume we have a query type `Q[T]` defined as follows:
160+
161+
```scala
162+
trait Q[T] extends Selectable:
163+
type Fields = NamedTuple.Map[NamedTuple.From[T], Q]
164+
def selectDynamic(fieldName: String) = ...
165+
```
166+
167+
Assume in the user domain:
168+
```scala
169+
case class City(zipCode: Int, name: String, population: Int)
170+
val city: Q[City]
171+
```
172+
Then
173+
```scala
174+
city.zipCode
175+
```
176+
has type `Q[Int]` and it expands to
177+
```scala
178+
city.selectDynamic("zipCode").asInstanceOf[Q[Int]]
179+
```
180+
122181
### The NamedTuple.From Type
123182

124183
The `NamedTuple` object contains a type definition
@@ -137,33 +196,36 @@ then `NamedTuple.From[City]` is the named tuple
137196
(zip: Int, name: String, population: Int)
138197
```
139198
The same works for enum cases expanding to case classes, abstract types with case classes as upper bound, alias types expanding to case classes
140-
and singleton types with case classes as underlying type.
199+
and singleton types with case classes as underlying type (in terms of the implementation, the `classSymbol` of a type must be a case class).
141200

142201
`From` is also defined on named tuples. If `NT` is a named tuple type, then `From[NT] = NT`.
143202

144203

204+
### Operations on Named Tuples
205+
206+
The operations on named tuples are defined in object [scala.NamedTuple](https://www.scala-lang.org/api/3.x/scala/NamedTuple$.html).
207+
145208
### Restrictions
146209

147-
The following restrictions apply to named tuple elements:
210+
The following restrictions apply to named tuples and named pattern arguments:
148211

149-
1. Either all elements of a tuple are named or none are named. It is illegal to mix named and unnamed elements in a tuple. For instance, the following is in error:
212+
1. Either all elements of a tuple or constructor pattern are named or none are named. It is illegal to mix named and unnamed elements in a tuple. For instance, the following is in error:
150213
```scala
151214
val illFormed1 = ("Bob", age = 33) // error
152215
```
153-
2. Each element name in a named tuple must be unique. For instance, the following is in error:
216+
2. Each element name in a named tuple or constructor pattern must be unique. For instance, the following is in error:
154217
```scala
155218
val illFormed2 = (name = "", age = 0, name = true) // error
156219
```
157-
3. Named tuples can be matched with either named or regular patterns. But regular tuples and other selector types can only be matched with regular tuple patterns. For instance, the following is in error:
220+
3. Named tuples and case classes can be matched with either named or regular patterns. But regular tuples and other selector types can only be matched with regular tuple patterns. For instance, the following is in error:
158221
```scala
159222
(tuple: Tuple) match
160223
case (age = x) => // error
161224
```
162-
4. Regular selector names `_1`, `_2`, ... are not allowed as names in named tuples.
225+
## Syntax Changes
163226

164-
### Syntax
165-
166-
The syntax of Scala is extended as follows to support named tuples:
227+
The syntax of Scala is extended as follows to support named tuples and
228+
named constructor arguments:
167229
```
168230
SimpleType ::= ...
169231
| ‘(’ NameAndType {‘,’ NameAndType} ‘)’
@@ -178,31 +240,11 @@ Patterns ::= Pattern {‘,’ Pattern}
178240
NamedPattern ::= id '=' Pattern
179241
```
180242
181-
### Named Pattern Matching
182-
183-
We allow named patterns not just for named tuples but also for case classes.
184-
For instance:
185-
```scala
186-
city match
187-
case c @ City(name = "London") => println(p.population)
188-
case City(name = n, zip = 1026, population = pop) => println(pop)
189-
```
190-
191-
Named constructor patterns are analogous to named tuple patterns. In both cases
192-
193-
- either all fields are named or none is,
194-
- every name must match the name some field of the selector,
195-
- names can come in any order,
196-
- not all fields of the selector need to be matched.
197-
198-
This revives SIP 43, with a much simpler desugaring than originally proposed.
199-
Named patterns are compatible with extensible pattern matching simply because
200-
`unapply` results can be named tuples.
201-
202243
### Source Incompatibilities
203244
204245
There are some source incompatibilities involving named tuples of length one.
205246
First, what was previously classified as an assignment could now be interpreted as a named tuple. Example:
247+
206248
```scala
207249
var age: Int
208250
(age = 1)
@@ -221,43 +263,3 @@ c f (age = 1)
221263
```
222264
will now construct a tuple as second operand instead of passing a named parameter.
223265

224-
### Computed Field Names
225-
226-
The `Selectable` trait now has a `Fields` type member that can be instantiated
227-
to a named tuple.
228-
229-
```scala
230-
trait Selectable:
231-
type Fields <: NamedTuple.AnyNamedTuple
232-
```
233-
234-
If `Fields` is instantiated in a subclass of `Selectable` to some named tuple type,
235-
then the available fields and their types will be defined by that type. Assume `n: T`
236-
is an element of the `Fields` type in some class `C` that implements `Selectable`,
237-
that `c: C`, and that `n` is not otherwise legal as a name of a selection on `c`.
238-
Then `c.n` is a legal selection, which expands to `c.selectDynamic("n").asInstanceOf[T]`.
239-
240-
It is the task of the implementation of `selectDynamic` in `C` to ensure that its
241-
computed result conforms to the predicted type `T`
242-
243-
As an example, assume we have a query type `Q[T]` defined as follows:
244-
245-
```scala
246-
trait Q[T] extends Selectable:
247-
type Fields = NamedTuple.Map[NamedTuple.From[T], Q]
248-
def selectDynamic(fieldName: String) = ...
249-
```
250-
251-
Assume in the user domain:
252-
```scala
253-
case class City(zipCode: Int, name: String, population: Int)
254-
val city: Q[City]
255-
```
256-
Then
257-
```scala
258-
city.zipCode
259-
```
260-
has type `Q[Int]` and it expands to
261-
```scala
262-
city.selectDynamic("zipCode").asInstanceOf[Q[Int]]
263-
```

docs/sidebar.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ subsection:
6868
- page: reference/other-new-features/export.md
6969
- page: reference/other-new-features/opaques.md
7070
- page: reference/other-new-features/opaques-details.md
71+
- page: reference/other-new-features/named-tuples.md
7172
- page: reference/other-new-features/open-classes.md
7273
- page: reference/other-new-features/parameter-untupling.md
7374
- page: reference/other-new-features/parameter-untupling-spec.md
@@ -154,7 +155,6 @@ subsection:
154155
- page: reference/experimental/cc.md
155156
- page: reference/experimental/purefuns.md
156157
- page: reference/experimental/tupled-function.md
157-
- page: reference/experimental/named-tuples.md
158158
- page: reference/experimental/modularity.md
159159
- page: reference/experimental/typeclasses.md
160160
- page: reference/experimental/runtimeChecked.md

0 commit comments

Comments
 (0)