Skip to content

Commit 56f8705

Browse files
authored
Merge pull request #2565 from dotty-staging/patmat-doc
Pattern matching documentation
2 parents 99a314f + 70d896c commit 56f8705

File tree

5 files changed

+197
-42
lines changed

5 files changed

+197
-42
lines changed

docs/_includes/features.html

Lines changed: 13 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@ <h1 id="so-features">So, features?</h1>
99
</colgroup>
1010
<tbody>
1111
<tr class="odd">
12-
<td>Union, intersection and <a href="http://docs.scala-lang.org/sips/pending/42.type.html">literal singleton types</a></td>
13-
<td>Implemented</td>
14-
</tr>
15-
<tr class="even">
16-
<td>Fast compilation (phase fusion)</td>
12+
<td><a href="http://dotty.epfl.ch/docs/reference/union-types.html">Union</a>, <a href="http://dotty.epfl.ch/docs/reference/intersection-types.html">intersection</a> and <a href="http://docs.scala-lang.org/sips/pending/42.type.html">literal singleton types</a></td>
1713
<td>Implemented</td>
1814
</tr>
1915
<tr class="odd">
@@ -24,90 +20,65 @@ <h1 id="so-features">So, features?</h1>
2420
<td><a href="https://github.com/scala/scala.github.com/pull/491">@static methods and fields</a></td>
2521
<td>Implemented</td>
2622
</tr>
27-
<tr class="odd">
28-
<td>Improved REPL with colors</td>
23+
<tr class="even">
24+
<td><a href="http://dotty.epfl.ch/#getting-started">SBT incremental build</a></td>
2925
<td>Implemented</td>
3026
</tr>
3127
<tr class="even">
32-
<td>Sbt incremental build</td>
28+
<td><a href="http://dotty.epfl.ch/docs/reference/pattern-matching.html"></a>Option-less pattern matching</td>
3329
<td>Implemented</td>
3430
</tr>
3531
<tr class="odd">
36-
<td>Non-blocking lazy vals</td>
32+
<td><a href="http://dotty.epfl.ch/docs/reference/auto-parameter-tupling.html">Automatic tupling of function parameters</a></td>
3733
<td>Implemented</td>
3834
</tr>
3935
<tr class="even">
40-
<td>Option-less pattern matching (based on <a href="https://github.com/scala/scala/pull/2848">name-based patmat</a>)</td>
41-
<td>Implemented</td>
42-
</tr>
43-
<tr class="odd">
44-
<td>Function arity adaptation</td>
36+
<td><a href="http://dotty.epfl.ch/docs/reference/multiversal-equality.html">Multiversal equality</a></td>
4537
<td>Implemented</td>
4638
</tr>
4739
<tr class="even">
48-
<td>Multiversal equality</td>
40+
<td><a href="http://dotty.epfl.ch/docs/reference/phantom-types.html">Phantom types</a></td>
4941
<td>Implemented</td>
5042
</tr>
5143
<tr class="odd">
52-
<td>Exhaustivity checks in pattern matching</td>
44+
<td><a href="http://dotty.epfl.ch/docs/reference/implicit-function-types.html">Implicit function types</a></td>
5345
<td>Implemented</td>
5446
</tr>
55-
<tr class="even">
56-
<td>Non-boxed arrays of value classes</td>
57-
<td>In progress</td>
58-
</tr>
5947
<tr class="odd">
60-
<td>Working contravariant implicits</td>
61-
<td>In progress</td>
62-
</tr>
63-
<tr class="even">
6448
<td><a href="https://github.com/dotty-linker/dotty">Auto-Specialization</a></td>
6549
<td>In progress</td>
6650
</tr>
67-
<tr class="odd">
68-
<td><a href="https://github.com/dotty-linker/dotty">Whole program optimizer</a></td>
69-
<td>In progress</td>
70-
</tr>
7151
<tr class="even">
72-
<td>HList &amp; HMaps/Record types</td>
52+
<td><a href="https://github.com/lampepfl/dotty/pull/1840">Whole program optimizer</a></td>
7353
<td>In progress</td>
7454
</tr>
7555
<tr class="odd">
76-
<td>Phantom types</td>
56+
<td><a href="https://github.com/lampepfl/dotty/pull/2199"></a>HList &amp; HMaps/Record types</td>
7757
<td>In progress</td>
7858
</tr>
7959
<tr class="even">
8060
<td></td>
8161
<td></td>
8262
</tr>
8363
<tr class="odd">
84-
<td>Implicit functions</td>
85-
<td>Considered</td>
86-
</tr>
87-
<tr class="even">
8864
<td>Effects</td>
8965
<td>Considered</td>
9066
</tr>
91-
<tr class="odd">
92-
<td>Auto-completion in repl</td>
93-
<td>Considered</td>
94-
</tr>
95-
<tr class="even">
96-
<td>Spec Option-less pattern matching</td>
97-
<td>Considered</td>
98-
</tr>
9967
</tbody>
10068
</table>
10169
</div>
10270
<h1 id="talks-on-dotty">Talks on Dotty?</h1>
10371
<ul>
72+
<li><a href="https://www.youtube.com/watch?v=GHzWqJKFCk4">Scala's Road Ahead</a> by Martin Odersky (<a href="http://www.slideshare.net/Odersky/scala-days-nyc-2016">slides</a>)</li>
10473
<li><a href="https://www.youtube.com/watch?v=WxyyJyB_Ssc">Compilers are Databases</a> by Martin Odersky (<a href="http://www.slideshare.net/Odersky/compilers-are-databases">slides</a>)</li>
10574
<li><a href="https://www.youtube.com/watch?v=aftdOFuVU1o">Exploring the future of Scala</a> by Dmitry Petrashko (<a href="https://d-d.me/scalaworld2015/#/">slides</a>)</li>
75+
<p><a href="http://dotty.epfl.ch/docs/resources/talks.html#deep-dive-with-dotty">Deep Dive with Dotty</a></p>
10676
</ul>
10777
<h1 id="i-have-more-questions">I have more questions!</h1>
10878
<div class="centered-text">
10979
<p>That’s great! We have more details on the <a href="{{ site.baseurl }}/docs">docs</a> and please join our <a href="https://gitter.im/lampepfl/dotty">Gitter channel</a>!</p>
11080
</div>
81+
<br/>
11182
</div>
11283
<div class="centered-subtitle">
11384
<a href="#why-dotty">
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
layout: doc-page
3+
title: "Option-less pattern matching"
4+
---
5+
6+
Dotty implementation of pattern matching was greatly simplified compared to scalac. From a user perspective, this means that Dotty generated patterns are a *lot* easier to debug, as variables all show up in debug modes and positions are correctly preserved.
7+
8+
Dotty supports a superset of scalac's [extractors](https://www.scala-lang.org/files/archive/spec/2.13/08-pattern-matching.html#extractor-patterns).
9+
10+
## Boolean Pattern
11+
12+
- Extractor defines `def unapply(x: T): Boolean`
13+
- Pattern-matching on exactly `0` patterns
14+
15+
For example:
16+
17+
<!-- To be kept in sync with tests/new/patmat-spec.scala -->
18+
19+
```scala
20+
object Even {
21+
def unapply(s: String): Boolean = s.size % 2 == 0
22+
}
23+
24+
"even" match {
25+
case s @ Even() => println(s"$s has an even number of characters")
26+
case s => println(s"$s has an odd number of characters")
27+
}
28+
// even has an even number of characters
29+
```
30+
31+
32+
## Product Pattern
33+
34+
- Extractor defines `def unapply(x: T): U`
35+
- `U <: Product`
36+
- `N > 0` is the maximum number of consecutive (parameterless `def` or `val`) `_1: P1` ... `_N: PN` members in `U`
37+
- Pattern-matching on exactly `N` patterns with types `P1, P2, ..., PN`
38+
39+
For example:
40+
41+
<!-- To be kept in sync with tests/new/patmat-spec.scala -->
42+
43+
```scala
44+
class FirstChars(s: String) extends Product {
45+
def _1 = s.charAt(0)
46+
def _2 = s.charAt(1)
47+
48+
// Not used by pattern matching: Product is only used as a marker trait.
49+
def canEqual(that: Any): Boolean = ???
50+
def productArity: Int = ???
51+
def productElement(n: Int): Any = ???
52+
}
53+
54+
object FirstChars {
55+
def unapply(s: String): FirstChars = new FirstChars(s)
56+
}
57+
58+
"Hi!" match {
59+
case FirstChars(char1, char2) =>
60+
println(s"First: $char1; Second: $char2")
61+
}
62+
// First: H; Second: i
63+
```
64+
65+
66+
## Seq Pattern
67+
68+
- Extractor defines `def unapplySeq(x: T): U`
69+
- `U` has (parameterless `def` or `val`) members `isEmpty: Boolean` and `get: S`
70+
- `S <: Seq[V]`
71+
- Pattern-matching on `N` pattern with types `V, V, ..., V`, where `N` is the runtime size of the `Seq`.
72+
73+
<!-- To be kept in sync with tests/new/patmat-spec.scala -->
74+
75+
```scala
76+
object CharList {
77+
def unapplySeq(s: String): Option[Seq[Char]] = Some(s.toList)
78+
}
79+
80+
"example" match {
81+
case CharList(c1, c2, c3, c4, _, _, _) =>
82+
println(s"$c1,$c2,$c3,$c4")
83+
case _ =>
84+
println("Expected *exactly* 7 characters!")
85+
}
86+
// e,x,a,m
87+
```
88+
89+
90+
## Name Based Pattern
91+
92+
- Extractor defines `def unapply(x: T): U`
93+
- `U` has (parameterless `def` or `val`) members `isEmpty: Boolean` and `get: S`
94+
- If there is exactly `1` pattern, pattern-matching on `1` pattern with type `S`
95+
- Otherwise `N > 0` is the maximum number of consecutive (parameterless `def` or `val`) `_1: P1` ... `_N: PN` members in `U`
96+
- Pattern-matching on exactly `N` patterns with types `P1, P2, ..., PN`
97+
98+
<!-- To be kept in sync with tests/new/patmat-spec.scala -->
99+
100+
```scala
101+
class Nat(val x: Int) {
102+
def get: Int = x
103+
def isEmpty = x < 0
104+
}
105+
106+
object Nat {
107+
def unapply(x: Int): Nat = new Nat(x)
108+
}
109+
110+
5 match {
111+
case Nat(n) => println(s"$n is a natural number")
112+
case _ => ()
113+
}
114+
// 5 is a natural number
115+
```
116+
117+
In case of ambiguities, *Product Pattern* is preferred over *Name Based Pattern*. This document reflects the state of pattern matching as currently implemented in Dotty. They are plans for further simplification, in particular to factor out *Product Pattern* and *Name Based Pattern* into a single type of extractor.

docs/sidebar.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ sidebar:
6363
url: docs/reference/changed/implicit-conversions.html
6464
- title: Vararg Patterns
6565
url: docs/reference/changed/vararg-patterns.html
66+
- title: Pettern matching
67+
url: docs/reference/changed/pattern-matching.html
6668
- title: Dropped Features
6769
subsection:
6870
- title: DelayedInit

tests/new/patmat-spec.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
even has an even number of characters
2+
First: H; Second: i
3+
e,x,a,m
4+
5 is a natural number

tests/run/patmat-spec.scala

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// To be kept in sync with docs/docs/reference/pattern-matching.md
2+
object Test {
3+
def main(args: Array[String]): Unit = {
4+
object Even {
5+
def unapply(s: String): Boolean = s.size % 2 == 0
6+
}
7+
8+
"even" match {
9+
case s @ Even() => println(s"$s has an even number of characters")
10+
case s => println(s"$s has an odd number of characters")
11+
}
12+
// even has an even number of characters
13+
14+
class FirstChars(s: String) extends Product {
15+
def _1 = s.charAt(0)
16+
def _2 = s.charAt(1)
17+
18+
// Not used by pattern matching: Product is only used as a marker trait.
19+
def canEqual(that: Any): Boolean = ???
20+
def productArity: Int = ???
21+
def productElement(n: Int): Any = ???
22+
}
23+
24+
object FirstChars {
25+
def unapply(s: String): FirstChars = new FirstChars(s)
26+
}
27+
28+
"Hi!" match {
29+
case FirstChars(char1, char2) =>
30+
println(s"First: $char1; Second: $char2")
31+
}
32+
// First: H; Second: i
33+
34+
object CharList {
35+
def unapplySeq(s: String): Option[Seq[Char]] = Some(s.toList)
36+
}
37+
38+
"example" match {
39+
case CharList(c1, c2, c3, c4, _, _, _) =>
40+
println(s"$c1,$c2,$c3,$c4")
41+
case _ =>
42+
println("Expected *exactly* 7 characters!")
43+
}
44+
// e,x,a,m
45+
46+
class Nat(val x: Int) {
47+
def get: Int = x
48+
def isEmpty = x < 0
49+
}
50+
51+
object Nat {
52+
def unapply(x: Int): Nat = new Nat(x)
53+
}
54+
55+
5 match {
56+
case Nat(n) => println(s"$n is a natural number")
57+
case _ => ()
58+
}
59+
// 5 is a natural number
60+
}
61+
}

0 commit comments

Comments
 (0)