Skip to content

Commit 0d8a2e4

Browse files
committed
Various improvments
1 parent 64d5e16 commit 0d8a2e4

File tree

1 file changed

+15
-26
lines changed

1 file changed

+15
-26
lines changed

_sips/sips/2021-06-25-pattern-matching-with-named-fields.md

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,8 @@ This SIP doesn't aim to allow pattern where parameters go into the pattern, e.g:
6161
```scala
6262
val map = Map("Berlin" -> 10, "Paris" -> 5)
6363

64-
map match {
64+
map match
6565
case Map("Paris" -> five) => five
66-
}
67-
68-
4 match {
69-
case n / 2 => "double of " + n.toString
70-
case _ => "odd"
71-
}
7266
```
7367

7468
//TODO: find references where this feature was requested
@@ -81,15 +75,14 @@ Before this was invalid syntax, so this shouldn't affect any existing Scala prog
8175

8276
### Mixed usage
8377

84-
Mixed patterns are allowed to keep the similarity, but have right now no motivational use case. Maybe those should be allowed:
78+
Mixed patterns, with positional and named patterns are allowed to keep the similarity.
79+
But they have no motivational use case. Maybe they should be disallowed.
8580

8681
```scala
8782
case User("Anna", city = c) => // Mixed usage seems wired
88-
case User(_, city = c) => // Leading underscore are espacially to useless (?)
83+
case User(_, city = c) => // Leading underscore are espacially useless
8984
```
9085

91-
//TODO: What's with user defined `unapply` on case classes? (Design)
92-
9386
## Implementation
9487

9588

@@ -114,17 +107,16 @@ case User(
114107
Without allowing user defined named arguments in pattern matching, the fact that class is a case class becomes part if it's public interface. Changing a case class to a normal class is a backward incompatible change, that library maintainers of to be aware. This is especially worrying since currently libraries where designed without this feature in mind.
115108

116109
```scala
117-
case class Age(years: Int)
118-
119-
class Age(val years: Int) {
120-
// equals, hashcode etc.
121-
}
122-
object Age {
123-
def unapply(age: Age): Option[Int] =
124-
Some(age.years)
125-
}
110+
class User(name: String, age: Int, city: String)
111+
object User
112+
def unapply(user: User): Option[(String, Int, String)] =
113+
???
114+
115+
// matching on User doesn't work anymore
126116
```
127117

118+
This limitation could be overcome by Named Tuple Arguments, discussed below.
119+
128120
## Alternatives
129121

130122
### Without any changes to the language
@@ -134,16 +126,13 @@ One alternative way of archiving most objectives, that is doable with current Sc
134126
```scala
135127
case class User(age: Int)
136128

137-
object User {
138-
object age {
129+
object User:
130+
object age:
139131
def unapply(user: User): Option[Int] =
140132
Some(user.age)
141-
}
142-
}
143133

144-
User(10) match {
134+
User(10) match
145135
case User.age(y) => y
146-
}
147136
```
148137

149138
Libraries like [Monocle][monocle] could be extended to reduce the boilerplate, but still some boilerplate would remain.

0 commit comments

Comments
 (0)