Skip to content

Commit 2b4de2d

Browse files
committed
reflect review comments
1 parent 6c56623 commit 2b4de2d

File tree

1 file changed

+60
-6
lines changed

1 file changed

+60
-6
lines changed

_overviews/core/collections-migration-213.md

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,83 @@ The module also provides [migratrion rules](https://github.com/scala/scala-colle
3232

3333
## scala.Seq migration
3434

35-
In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A]`, instead of `scala.collection.Seq[A]`. This change requires some planning depending on how your code is going to be used.
36-
37-
If you're making an application, and simply migrating a Scala 2.12 code base to 2.13, it might be ok to keep using `scala.Seq` in your code.
35+
In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A]` ("ISeq"), instead of `scala.collection.Seq[A]` ("CSeq"). This change requires some planning depending on how your code is going to be used.
3836

3937
If you're making a library intended to be used by other programmers, then using `scala.Seq` or varargs is going to be a breaking change in the API semantics. For example, if there was a function `def orderFood(order: Seq[Order]): Seq[Food]`, previously the library user would have been able to pass in an array of `Order`, but it won't work for 2.13.
4038

4139
- if you cross build with Scala 2.12 and want to maintain the API semantics for 2.13 version of your library, or
4240
- if your library users frequently uses mutable collections such as `Array`
4341

44-
you can import `scala.collection.Seq` ("CSeq") explicitly in your code.
42+
you can import collection Seq explicitly in your code.
4543

4644
~~~ scala
4745
import scala.collection.Seq
46+
47+
object FoodToGo {
48+
def orderFood(order: Seq[Order]): Seq[Food]
49+
}
50+
~~~
51+
52+
Note that this might still break the source compatibility if `scala.Seq` (or just `Seq`) appears in the source code.
53+
54+
~~~ scala
55+
val food: Seq[Food] = FoodToGo.orderFood(order) // won't compile
4856
~~~
4957

50-
In the future when your API is able to break the source compatibility, it might also make sense to migrate towards the `scala.collection.immutable.Seq` ("ISeq") for both Scala 2.12 and Scala 2.13.
58+
Since `Seq`, an alias for ISeq in 2.13, is narrower than CSeq, the above code will no longer compile. One workaround would be to ask your users to add `toSeq`, which returns ISeq.
5159

5260
~~~ scala
53-
import scala.collection.immutable.Seq
61+
val food: Seq[Food] = FoodToGo.orderFood(order).toSeq // add .toSeq
5462
~~~
5563

64+
Another workaround might be to accept CSeq, but return ISeq.
65+
66+
~~~ scala
67+
import scala.collection.{ Seq => CSeq }
68+
import scala.collection.immutable.{ Seq => ISeq }
69+
70+
object FoodToGo {
71+
def orderFood(order: CSeq[Order]): ISeq[Food]
72+
}
73+
~~~
74+
75+
In the future when your API is able to break the source compatibility, it might also make sense to migrate towards ISeq for both Scala 2.12 and Scala 2.13.
76+
77+
~~~ scala
78+
import scala.collection.immutable.{ Seq => ISeq }
79+
80+
object FoodToGo {
81+
def orderFood(order: ISeq[Order]): ISeq[Food]
82+
}
83+
~~~
84+
85+
Similarly, if you're making an end-user application, unifying to CSeq might be the easier and safer initial path especially for a larger and complex code base. Switching to ISeq will be a more advanced refactoring.
86+
5687
Note that in Scala 2.13 the sequence passed into as a varargs as `orderFood(xs: _*)` must also be immutable. This is because the sequence passed in as a varargs must conform to `scala.Seq` according to [SLS 6.6](https://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#function-applications). Thus, if your API exposes varargs it will be an unavoidable breaking change. This might affect Java interoperability.
5788

89+
### Masking scala.Seq
90+
91+
To use the compiler to bad the use of plain `Seq`, you can declare your own `Seq` to mask `scala.Seq`.
92+
93+
~~~ scala
94+
package example
95+
96+
import scala.annotation.compileTimeOnly
97+
98+
/**
99+
* In Scala 2.13, scala.Seq moved from scala.collection.Seq to scala.collection.immutable.Seq.
100+
* In this code base, we'll require you to name ISeq or CSeq.
101+
*
102+
* import scala.collection.{ Seq => CSeq }
103+
* import scala.collection.immutable.{ Seq => ISeq }
104+
*
105+
* This Seq trait is a dummy type to prevent the use of `Seq`.
106+
*/
107+
@compileTimeOnly("Use ISeq or CSeq") private[example] trait Seq[A1, F1[A2], A3]
108+
~~~
109+
110+
This might be useful during the transition period where you have to remember to import CSeq.
111+
58112
## What are the breaking changes?
59113

60114
The following table summarizes the breaking changes. The "Automatic Migration Rule" column gives the name of the migration rule that can be used to automatically update old code to the new expected form.

0 commit comments

Comments
 (0)