Skip to content

Commit 66b6770

Browse files
committed
Corrections of the tabs.
- Change scala 3 only by scala 2 only - Re-add highlight parts
1 parent 1c9d9bd commit 66b6770

File tree

2 files changed

+59
-89
lines changed

2 files changed

+59
-89
lines changed

Gemfile.lock

+3
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ GEM
219219
jekyll-feed (~> 0.9)
220220
jekyll-seo-tag (~> 2.1)
221221
minitest (5.17.0)
222+
nokogiri (1.14.2-x86_64-darwin)
223+
racc (~> 1.4)
222224
nokogiri (1.14.2-x86_64-linux)
223225
racc (~> 1.4)
224226
octokit (4.25.1)
@@ -263,6 +265,7 @@ GEM
263265
zeitwerk (2.6.7)
264266

265267
PLATFORMS
268+
x86_64-darwin-22
266269
x86_64-linux
267270

268271
DEPENDENCIES

_overviews/scala3-migration/incompat-other-changes.md

+56-89
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ The solution is to make the constructor private, since the class is private.
108108

109109
In Scala 3, overriding a concrete def with an abstract def causes subclasses to consider the def abstract, whereas in Scala 2 it was considered as concrete.
110110

111-
{% tabs scala-3-abstract_1 %}
112-
{% tab 'Scala 3 Only' %}
111+
{% tabs scala-2-abstract_1 %}
112+
{% tab 'Scala 2 Only' %}
113113

114114
In the following piece of code, the `bar` method in `C` is considered concrete by the Scala 2.13 compiler but abstract by the Scala 3 compiler, causing the following error.
115115
~~~ scala
@@ -121,7 +121,7 @@ trait B extends A {
121121
def bar(x: Int): Int
122122
}
123123

124-
class C extends B // Error: class C needs to be abstract, since def bar(x: Int): Int is not defined
124+
class C extends B // In Scala 3, Error: class C needs to be abstract, since def bar(x: Int): Int is not defined
125125
~~~
126126

127127
This behavior was decided in [Dotty issue #4770](https://github.com/lampepfl/dotty/issues/4770).
@@ -135,8 +135,8 @@ An easy fix is simply to remove the abstract def, since in practice it had no ef
135135
The companion object of a case class does not extend any of the `Function{0-23}` traits anymore.
136136
In particular, it does not inherit their methods: `tupled`, `curried`, `andThen`, `compose`...
137137

138-
{% tabs companion_1 class=tabs-scala-version %}
139-
{% tab 'Scala 2' for=companion_1 %}
138+
{% tabs scala-2-companion_1 %}
139+
{% tab 'Scala 2 Only' %}
140140

141141
For instance, this is not permitted anymore:
142142
~~~ scala
@@ -146,21 +146,23 @@ Foo.curried(1)(true)
146146
Foo.tupled((2, false))
147147
~~~
148148
{% endtab %}
149-
{% tab 'Scala 3' for=companion_1 %}
149+
{% endtabs %}
150150

151151
A cross-compiling solution is to explicitly eta-expand the method `Foo.apply`.
152-
~~~ scala
153-
case class Foo(x: Int, b: Boolean)
152+
{% highlight diff %}
154153

155-
(Foo.apply _).curried(1)(true)
156-
(Foo.apply _).tupled((2, false))
157-
~~~
154+
-Foo.curried(1)(true)
155+
+(Foo.apply _).curried(1)(true)
158156

159-
Or, for performance reasons, you can introduce an intermediate function value.
157+
-Foo.tupled((2, false))
158+
+(Foo.apply _).tupled((2, false))
159+
{% endhighlight %}
160160

161-
~~~ scala
162-
case class Foo(x: Int, b: Boolean)
161+
{% tabs scala-3-companion_2 %}
162+
{% tab 'Scala 3 Only' %}
163163

164+
Or, for performance reasons, you can introduce an intermediate function value.
165+
~~~ scala
164166
val fooCtr: (Int, Boolean) => Foo = (x, b) => Foo(x, b)
165167

166168
fooCtr.curried(1)(true)
@@ -208,45 +210,39 @@ object Location {
208210
def unapply(location: Location): Location = location
209211
}
210212
~~~
211-
212-
Consequently the following code does not compile anymore.
213-
~~~ scala
214-
def tuple(location: Location): (Int, Int) = {
215-
Location.unapply(location).get // [E008] Not Found Error: value get is not a member of Location
216-
}
217-
~~~
218213
{% endtab %}
219214
{% endtabs %}
220215

221-
A possible solution is to use pattern binding:
222-
223-
{% tabs unaply_3 class=tabs-scala-version %}
224-
{% tab 'Scala 2' for=unaply_3 %}
216+
{% tabs scala-2-unapply_3 %}
217+
{% tab 'Scala 2 Only' %}
225218

219+
Consequently the following code does not compile anymore in Scala 3.
226220
~~~ scala
227221
def tuple(location: Location): (Int, Int) = {
228-
Location.unapply(location).get
222+
Location.unapply(location).get // [E008] In Scala 3, Not Found Error: value get is not a member of Location
229223
}
230224
~~~
231225
{% endtab %}
232-
{% tab 'Scala 3' for=unaply_3 %}
233-
~~~ scala
226+
{% endtabs %}
227+
228+
A possible solution, in Scala 3, is to use pattern binding:
229+
230+
{% highlight diff %}
234231
def tuple(location: Location): (Int, Int) = {
235-
val Location(lat, lon) = location
236-
(lat, lon)
232+
- Location.unapply(location).get
233+
+ val Location(lat, lon) = location
234+
+ (lat, lon)
237235
}
238-
~~~
239-
{% endtab %}
240-
{% endtabs %}
236+
{% endhighlight %}
241237

242238
## Invisible Bean Property
243239

244240
The getter and setter methods generated by the `BeanProperty` annotation are now invisible in Scala 3 because their primary use case is the interoperability with Java frameworks.
245241

246-
{% tabs scala-3-bean_1 %}
247-
{% tab 'Scala 3 Only' %}
242+
{% tabs scala-2-bean_1 %}
243+
{% tab 'Scala 2 Only' %}
248244

249-
For instance, in the below example:
245+
For instance, the below Scala 2 code would fail to compile in Scala 3:
250246

251247
~~~ scala
252248
class Pojo() {
@@ -255,36 +251,24 @@ class Pojo() {
255251

256252
val pojo = new Pojo()
257253

258-
pojo.setFooBar("hello") // [E008] Not Found Error: value setFooBar is not a member of Pojo
254+
pojo.setFooBar("hello") // [E008] In Scala 3, Not Found Error: value setFooBar is not a member of Pojo
259255

260-
println(pojo.getFooBar()) // [E008] Not Found Error: value getFooBar is not a member of Pojo
256+
println(pojo.getFooBar()) // [E008] In Scala 3, Not Found Error: value getFooBar is not a member of Pojo
261257
~~~
262258
{% endtab %}
263259
{% endtabs %}
264260

265-
The solution is to call the more idiomatic `pojo.fooBar` getter and setter.
266-
267-
{% tabs bean_2 class=tabs-scala-version %}
268-
{% tab 'Scala 2' for=bean_2 %}
261+
In Scala 3, the solution is to call the more idiomatic `pojo.fooBar` getter and setter.
269262

270-
~~~ scala
271-
val pojo = new Pojo()
272-
273-
pojo.setFooBar("hello")
274-
275-
println(pojo.getFooBar())
276-
~~~
277-
{% endtab %}
278-
{% tab 'Scala 3' for=bean_2 %}
279-
~~~ scala
263+
{% highlight diff %}
280264
val pojo = new Pojo()
281265

282-
pojo.fooBar = "hello"
266+
-pojo.setFooBar("hello")
267+
+pojo.fooBar = "hello"
283268

284-
println(pojo.fooBar)
285-
~~~
286-
{% endtab %}
287-
{% endtabs %}
269+
-println(pojo.getFooBar())
270+
+println(pojo.fooBar)
271+
{% endhighlight %}
288272

289273
## `=> T` as Type Argument
290274

@@ -315,40 +299,31 @@ The solution depends on the situation. In the given example, you can either:
315299

316300
Scala 3 cannot reduce the application of a higher-kinded abstract type member to the wildcard argument.
317301

318-
{% tabs scala-3-wildcard_1 %}
319-
{% tab 'Scala 3 Only' %}
302+
{% tabs scala-2-wildcard_1 %}
303+
{% tab 'Scala 2 Only' %}
320304

321-
For instance, the following example does not compile.
305+
For instance, the below Scala 2 code would fail to compile in Scala 3:
322306

323307
~~~ scala
324308
trait Example {
325309
type Foo[A]
326310

327-
def f(foo: Foo[_]): Unit // [E043] Type Error: unreducible application of higher-kinded type Example.this.Foo to wildcard arguments
311+
def f(foo: Foo[_]): Unit // [E043] In Scala 3, Type Error: unreducible application of higher-kinded type Example.this.Foo to wildcard arguments
328312
}
329313
~~~
330314
{% endtab %}
331315
{% endtabs %}
332316

333317
We can fix this by using a type parameter:
334318

335-
{% tabs wildcard_2 class=tabs-scala-version %}
336-
{% tab 'Scala 2' for=wildcard_2 %}
337-
338-
~~~ scala
339-
def f(foo: Foo[_]): Unit
340-
~~~
341-
{% endtab %}
342-
{% tab 'Scala 3' for=wildcard_2 %}
343-
~~~ scala
344-
def f[A](foo: Foo[A]): Unit
345-
~~~
346-
{% endtab %}
347-
{% endtabs %}
319+
{% highlight diff %}
320+
-def f(foo: Foo[_]): Unit
321+
+def f[A](foo: Foo[A]): Unit
322+
{% endhighlight %}
348323

349324
But this simple solution does not work when `Foo` is itself used as a type argument.
350-
{% tabs shared-wildcard_3 %}
351-
{% tab 'Scala 2 and 3' %}
325+
{% tabs scala-2-wildcard_2 %}
326+
{% tab 'Scala 2 Only' %}
352327
~~~ scala
353328
def g(foos: Seq[Foo[_]]): Unit
354329
~~~
@@ -357,17 +332,9 @@ def g(foos: Seq[Foo[_]]): Unit
357332

358333
In such case, we can use a wrapper class around `Foo`:
359334

360-
{% tabs wildcard_4 class=tabs-scala-version %}
361-
{% tab 'Scala 2' for=wildcard_4 %}
362-
~~~ scala
363-
def g(foos: Seq[Foo[_]]): Unit
364-
~~~
365-
{% endtab %}
366-
{% tab 'Scala 3' for=wildcard_4 %}
367-
~~~ scala
368-
class FooWrapper[A](foo: Foo[A])
335+
{% highlight diff %}
336+
+class FooWrapper[A](foo: Foo[A])
369337

370-
def g(foos: Seq[FooWrapper[_]]): Unit
371-
~~~
372-
{% endtab %}
373-
{% endtabs %}
338+
-def g(foos: Seq[Foo[_]]): Unit
339+
+def g(foos: Seq[FooWrapper[_]]): Unit
340+
{% endhighlight %}

0 commit comments

Comments
 (0)