Skip to content

Commit 8bb0f10

Browse files
committed
Flesh out details
1 parent c55e861 commit 8bb0f10

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

_sips/sips/2022-02-25-pattern-matching-with-named-fields.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ redirect_from: /sips/pending/2021-06-25-named-pattern-matching.html
1414

1515
## Motivation
1616

17-
An readable, extendible, and intuitive way to deconstruct case classes in pattern matching.
17+
An readable, extensible, and intuitive way to deconstruct case classes in pattern matching.
1818

1919
Link to work in progress implementation lives here: https://github.com/Jentsch/dotty
2020

@@ -137,28 +137,32 @@ The reason to pull the names out, instead of keeping them near to their type, is
137137

138138
## Implementation
139139

140-
'Simple' rewrite of patterns. If a pattern with a name is encountered, the compiler looks up the index of those names and places the tree accordingly.
140+
If a pattern with a name is encountered, the compiler looks up list of provided names and places the trees accordingly.
141+
142+
The list of names either provided by the return type of the unapply method or by the constructor list of the case class.
141143

142144
Example:
143145

144146
```scala
145147
// a match clause like
146-
case User(age = <tree>) => ???
148+
case User(<tree1>, city = <tree2>) => ???
147149

148150
// gets rewritten to:
149151
case User(
152+
<tree1>, // because tree1 is positional pattern
150153
_, // because name isn't mentioned
151-
<tree>, // because age is the second parameter of user
152-
_ // because city isn't mentioned
154+
<tree2>, // because city is the third parameter of user
153155
)
154156
```
155157

158+
This allows us to glace over the details of how pattern matching gets desugared further down the line.
159+
156160
## Drawbacks
157161

158162
### Allow skipping arguments
159163

160-
Whenever a single named argument is used in pattern, the pattern can have fewer arguments than the unapply.
161-
This leads to inconsistency, as pointed out by Lionel Parreaux in the [Scala Contributors Thread](https://contributors.scala-lang.org/t/pattern-matching-with-named-fields/1829/44). This could lead users to use a named pattern, just to skip all parameters.
164+
Whenever a single named argument is used in pattern, the pattern can have fewer arguments than the unapply provides. This is driven by the motivation the make pattern matching extensible.
165+
But this leads to (arguably small) inconsistency, as pointed out by Lionel Parreaux in the [Scala Contributors Thread](https://contributors.scala-lang.org/t/pattern-matching-with-named-fields/1829/44). This could lead users to use a named pattern, just to skip all parameters.
162166

163167
```scala
164168
case User(age = _) => "Just wanted to use the extractor, lol!"
@@ -185,9 +189,11 @@ In addition, this breaks the intuitive similarity between construction and decon
185189

186190
### Alternative desugaring
187191

192+
As the above described desugaring has its drawbacks.Here are some alternatives with other drawbacks, and maybe better trade-offs.
193+
188194
#### Use underscore methods
189195

190-
In the sprit of https://dotty.epfl.ch/docs/reference/changed-features/pattern-matching.html#name-based-match:
196+
In the sprit of [name based pattern matching](https://dotty.epfl.ch/docs/reference/changed-features/pattern-matching.html#name-based-match):
191197

192198
```scala
193199
object User:
@@ -203,11 +209,13 @@ Pro:
203209

204210
* allows to add more fields
205211
* allows `@deprecatedName`
212+
* is the only desugaring, that doesn't use string literals
206213

207214
Con:
208215

209216
* How to detect that a name means the same as a position? Maybe detect simple patterns like the last line in the example?
210-
* long and verbose, without any shortcuts
217+
* long and verbose, without any shortcuts in sight
218+
* An underscore at the beginning of a name is an unheard of pattern, even in Scala. This could accidentally expose fields, which weren't suppose to become fields.
211219

212220
#### Annotated `unapply` method
213221

@@ -255,7 +263,7 @@ This would be more generic and could handle user defined extractors.
255263
Lionel Parreaux proposed a more powerful mechanism, where if guards of cases could them self contains destructuring patterns.
256264

257265
```scala
258-
case user: User if Age(years) <- user => years
266+
case user: User if Age(years) <- user.age => years
259267
case User(age = Age(years)) => years // both cases do the same thing
260268
```
261269

@@ -265,6 +273,8 @@ His proposal is strictly more powerful, but arguably less intuitive. Both, Patte
265273

266274
It could be useful to add extractors with just named fields to sealed traits and enums.
267275

276+
What would reuse would look like? What is desirable?
277+
268278
## References
269279

270280
* [Scala Contributors Thread][contributors-thread]

0 commit comments

Comments
 (0)