You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _overviews/core/collections-migration-213.md
+81-36Lines changed: 81 additions & 36 deletions
Original file line number
Diff line number
Diff line change
@@ -31,95 +31,140 @@ The [scala-collection-compat](https://github.com/scala/scala-collection-compat)
31
31
32
32
The module also provides [migratrion rules](https://github.com/scala/scala-collection-compat#migration-tool) for [scalafix](https://scalacenter.github.io/scalafix/docs/users/installation.html) that can update a project's source code to work with the 2.13 collections library.
33
33
34
-
## scala.Seq and scala.IndexedSeq migration
34
+
## scala.Seq, varargs and scala.IndexedSeq migration
35
35
36
-
In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A]` ("ISeq"), instead of `scala.collection.Seq[A]` ("CSeq"). Similarly,`scala.IndexedSeq[+A]` is an alias for `scala.collection.immutable.IndexedSeq[A]`. These changes require some planning depending on how your code is going to be used.
36
+
In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A]`, instead of `scala.collection.Seq[A]`, and`scala.IndexedSeq[+A]` is an alias for `scala.collection.immutable.IndexedSeq[A]`. These changes require some planning depending on how your code is going to be used.
37
37
38
-
If you're making a library intended to be used by other programmers, then using `scala.Seq`, `scala.IndexedSeq`, or vararg 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.
38
+
The change in definition of `scala.Seq` also has the effect of making the type of varargs parameters immutable sequences, due to [SLS 6.6][], so in
39
+
a method such as `orderFood(xs: _*)` the varargs parameter `xs` must be an immutable sequence.
39
40
40
-
- if you cross build with Scala 2.12 and want to maintain the API semantics for 2.13 version of your library, or
41
-
- if your library users frequently uses mutable collections such as `Array`
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.
89
+
The simplest workaround is to ask your users to call `.toSeq` on the result which will return an immutable Seq,
90
+
and only copy data if the sequence wasn't immutable:
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.
112
+
### Option 3: use immutable sequences
113
+
114
+
The third migration strategy is to change your API to use immutable sequences for both parameter and result
115
+
types. When cross-building your library for Scala 2.12 and 2.13 this could either mean:
116
+
117
+
- continuing to use `scala.Seq` which means it stays source and binary-compatible in 2.12, but would have to
118
+
have immutable sequence semantics (but that might already be the case).
119
+
- switch to explicitly using immutable Seq in both Scala 2.12 and 2.13, which means breaking source, binary and
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.
87
-
88
-
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.
89
-
90
-
### Masking scala.Seq
130
+
### Shadowing scala.Seq and scala.IndexedSeq
91
131
92
-
To use the compiler to bad the use of plain `Seq`, you can declare your own `Seq` to mask `scala.Seq`.
132
+
You maybe be interested in entirely banning plain `Seq` usage. You can use the compiler to do so by declaring
133
+
your own package-level (and package private) `Seq` type which will mask `scala.Seq`.
93
134
94
135
~~~scala
95
136
packageexample
96
137
97
138
importscala.annotation.compileTimeOnly
98
139
99
140
/**
100
-
* In Scala 2.13, scala.Seq moved from scala.collection.Seq to scala.collection.immutable.Seq.
101
-
* In this code base, we'll require you to name ISeq or CSeq.
141
+
* In Scala 2.13, `scala.Seq` changed from aliasing `scala.collection.Seq` to aliasing
142
+
* `scala.collection.immutable.Seq`. In this code base usage of unqualified `Seq` is banned: use
0 commit comments