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
+83-36Lines changed: 83 additions & 36 deletions
Original file line number
Diff line number
Diff line change
@@ -31,95 +31,142 @@ 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
+
This 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.
87
+
The simplest workaround is to ask your users to call `.toSeq` on the result which will return an immutable Seq,
88
+
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.
110
+
### Option 3: use immutable sequences
111
+
112
+
The third migration strategy is to change your API to use immutable sequences for both parameter and result
113
+
types. When cross-building your library for Scala 2.12 and 2.13 this could either mean:
114
+
115
+
- continuing to use `scala.Seq` which means it stays source and binary-compatible in 2.12, but would have to
116
+
have immutable sequence semantics (but that might already be the case).
117
+
- switch to explicitly using immutable Seq in both Scala 2.12 and 2.13, which means breaking source, binary and
118
+
semantic compatibility in 2.12:
77
119
78
120
~~~scala
79
-
importscala.collection.immutable.{ Seq=>ISeq }
121
+
importscala.collection.{ immutable=>sci }
80
122
81
123
objectFoodToGo {
82
-
deforderFood(order: ISeq[Order]):ISeq[Food]
124
+
deforderFood(order: sci.Seq[Order]):sci.Seq[Food]
83
125
}
84
126
~~~
85
127
86
-
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
128
+
### Shadowing scala.Seq and scala.IndexedSeq
91
129
92
-
To use the compiler to bad the use of plain `Seq`, you can declare your own `Seq` to mask `scala.Seq`.
130
+
You maybe be interested in entirely banning plain `Seq` usage. You can use the compiler to do so by declaring
131
+
your own package-level (and package private) `Seq` type which will mask `scala.Seq`.
93
132
94
133
~~~scala
95
134
packageexample
96
135
97
136
importscala.annotation.compileTimeOnly
98
137
99
138
/**
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.
139
+
* In Scala 2.13, `scala.Seq` changed from aliasing `scala.collection.Seq` to aliasing
140
+
* `scala.collection.immutable.Seq`. In this code base usage of unqualified `Seq` is banned: use
0 commit comments