Skip to content

Commit a4d12d5

Browse files
committed
Add kind-projector migration page
1 parent 2d2ea26 commit a4d12d5

File tree

4 files changed

+145
-1
lines changed

4 files changed

+145
-1
lines changed

_overviews/scala3-migration/options-new.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ type: section
44
description: This chapter lists all the new compiler options in Scala 3
55
num: 23
66
previous-page: options-lookup
7-
next-page:
7+
next-page: plugin-intro
88
---
99

1010
The current page only contains the options that were added in Scala 3.0.x.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
title: Compiler Plugins
3+
type: chapter
4+
description: This section shows how to migrate from using Scala 2 compiler plugins
5+
num: 24
6+
previous-page: options-new
7+
next-page: plugin-kind-projector
8+
---
9+
10+
Scala 3 includes some features that were previously provided by a compiler plugin.
11+
This chapter gives more detail on how to migrate from using a specific compiler plugin to Scala 3.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
title: Kind Projector Migration
3+
type: section
4+
description: This section shows how to migrate from the kind-projector plugin to Scala 3 kind-projector syntax
5+
num: 25
6+
previous-page: plugin-intro
7+
next-page:
8+
---
9+
10+
In the future, Scala 3 will use the `_` underscore symbol for placeholders in type lambdas---just as the underscore is currently used for placeholders in (ordinary) term-level lambdas.
11+
12+
```scala
13+
14+
```
15+
16+
The new type lambda syntax is not enabled by default, to enable it, use a compiler flag `-Ykind-projector:underscores`. Note that enabling underscore type lambdas will disable usage of `_` as a wildcard, you will only be able to write wildcards using the `?` symbol.
17+
18+
If you wish to cross-compile a project for Scala 2 & Scala 3 while using underscore type lambdas for both, you may do so starting with [kind-projector](https://github.com/typelevel/kind-projector) version `0.13.0` and up and Scala 2 versions `2.13.6` and `2.12.14`.
19+
To enable it, add the compiler flags `-Xsource:3 -P:kind-projector:underscore-placeholders` to your build.
20+
As in Scala 3, this will disable usage of `_` as a wildcard, however, the flag `-Xsource:3` will allow you to replace it with the `?` symbol.
21+
22+
The following `sbt` configuration will set up the correct flags to cross-compile with new syntax:
23+
24+
```scala
25+
ThisBuild / scalacOptions ++= {
26+
CrossVersion.partialVersion(scalaVersion.value) match {
27+
case Some((3, _)) => Seq("-Ykind-projector:underscores")
28+
case Some((2, 13)) => Seq("-Xsource:3", "-P:kind-projector:underscore-placeholders"))
29+
}
30+
}
31+
```
32+
33+
## Migrating to New Syntax
34+
35+
To use underscores for type-lambdas in existing kind-projector enabled code, replace `*` or `?` type lambda placeholders with `_`.
36+
37+
In turn, you will also have to rewrite all usages of `_` as the wildcard to use `?` symbol.
38+
39+
For example the following usage of the wildcard:
40+
41+
```scala
42+
def getWidget(widgets: Set[_ <: Widget], name: String): Option[Widget] = widgets.find(_.name == name)
43+
```
44+
45+
Must be rewritten to:
46+
47+
```scala
48+
def getWidget(widgets: Set[? <: Widget], name: String): Option[Widget] = widgets.find(_.name == name)
49+
```
50+
51+
And the following usages of kind-projector's `*` placeholder:
52+
53+
```scala
54+
Tuple2[*, Double] // equivalent to: type R[A] = Tuple2[A, Double]
55+
Either[Int, +*] // equivalent to: type R[+A] = Either[Int, A]
56+
Function2[-*, Long, +*] // equivalent to: type R[-A, +B] = Function2[A, Long, B]
57+
```
58+
59+
Must be rewritten to:
60+
61+
```scala
62+
Tuple2[_, Double] // equivalent to: type R[A] = Tuple2[A, Double]
63+
Either[Int, +_] // equivalent to: type R[+A] = Either[Int, A]
64+
Function2[-_, Long, +_] // equivalent to: type R[-A, +B] = Function2[A, Long, B]
65+
```
66+
67+
## Compiling Existing Code
68+
69+
Even without migrating to underscore type lambdas, you will likely be able to compile most of it with Scala 3 without changes.
70+
71+
Use the flag `-Ykind-projector` to enable support for `*`-based type lambdas (without enabling underscore type lambdas), the following forms will now compile:
72+
73+
```scala
74+
Tuple2[*, Double] // equivalent to: type R[A] = Tuple2[A, Double]
75+
Either[Int, +*] // equivalent to: type R[+A] = Either[Int, A]
76+
Function2[-*, Long, +*] // equivalent to: type R[-A, +B] = Function2[A, Long, B]
77+
```
78+
79+
## Rewriting Incompatible Constructs
80+
81+
Scala 3's `-Ykind-projector` & `-Ykind-projector:underscores` implement only a subset of `kind-projector` syntax, in particular they do not implement:
82+
83+
* higher-kinded type lambda placeholders
84+
* higher-kinded named type lambda parameters
85+
* The `Lambda` keyword (`λ` is still supported)
86+
87+
You must rewrite ALL of the following forms:
88+
89+
```scala
90+
// classic
91+
EitherT[*[_], Int, *] // equivalent to: type R[F[_], B] = EitherT[F, Int, B]
92+
// underscores
93+
EitherT[_[_], Int, _] // equivalent to: type R[F[_], B] = EitherT[F, Int, B]
94+
// named λ
95+
λ[(F[_], A) => EitherT[F, Int, A]]
96+
// named Lambda
97+
Lambda[(F[_], A) => EitherT[F, Int, A]]
98+
```
99+
100+
Into the following long-form to cross-compile with Scala 3:
101+
102+
```scala
103+
type MyLambda[F[_], A] = EitherT[F, Int, A]
104+
MyLambda
105+
```
106+
107+
Alternatively you may use Scala 3's [Native Type Lambdas](https://dotty.epfl.ch/docs/reference/new-types/type-lambdas.html) if you do not need to cross-compile:
108+
109+
```scala
110+
[F[_], A] =>> EitherT[F, Int, A]
111+
```
112+
113+
For `Lambda` you must rewrite the following form:
114+
115+
```scala
116+
Lambda[(`+E`, `+A`) => Either[E, A]]
117+
```
118+
119+
To the following to cross-compile:
120+
121+
```scala
122+
λ[(`+E`, `+A`) => Either[E, A]]
123+
```
124+
125+
Or alternatively to Scala 3 type lambdas:
126+
127+
```scala
128+
[E, A] =>> Either[E, A]
129+
```
130+
131+
Note: Scala 3 type lambdas no longer need `-` or `+` variance markers on parameters, these are now inferred.

_overviews/scala3-migration/tutorial-prerequisites.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ AdditionalLy, we now have the following features that make `kind-projector` not
115115
- [Polymorphic Functions](http://dotty.epfl.ch/docs/reference/new-types/polymorphic-function-types.html)
116116
- [Kind Polymorphism](http://dotty.epfl.ch/docs/reference/other-new-features/kind-polymorphism.html)
117117

118+
You can learn more about the Kind Projector migration in its [dedicated page](plugin-kind-projector.html).
119+
118120
## Runtime reflection
119121

120122
`scala-reflect` will not be ported to Scala 3 because it exposes Scala 2 compiler internals that do not exist in Scala 3.

0 commit comments

Comments
 (0)