-
Notifications
You must be signed in to change notification settings - Fork 1k
Add guidance on how to migrate scala.Seq #1326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Not being able to pass an array I don't think is "a breaking change in the API semantics". It's just source-incompatible. I actually think continuing to use |
Co-Authored-By: Dale Wijnand <344610+dwijnand@users.noreply.github.com>
Co-Authored-By: Dale Wijnand <344610+dwijnand@users.noreply.github.com>
Co-Authored-By: Dale Wijnand <344610+dwijnand@users.noreply.github.com>
The meaning of your API changed, so I think it's a breaking change. For most libraries it might be an acceptable change, but for others it might not work. We don't know. The vararg you have no option, but you do have an option to use CSeq for your own API. |
import scala.collection.Seq | ||
~~~ | ||
|
||
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it doesn't seem like you refer to "ISeq" or "CSeq" anywhere, so the parentheticals can probably be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added commits that ended up adding references to ISeq and CSeq.
- if you cross build with Scala 2.12 and want to maintain the API semantics for 2.13 version of your library, or | ||
- if your library users frequently uses mutable collections such as `Array` | ||
|
||
you can import `scala.collection.Seq` ("CSeq") explicitly in your code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth mentioning that this is a potentially source-breaking change. If a user in 2.12 has:
// `Seq` is the default `scala.Seq`
val a: Seq[Food] = orderFood(myOrder)
Then that will no longer compile in 2.13
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, it might be a good strategy for APIs to only move to immutable.Seq
in the result type, but keep accepting collection.Seq
arguments, if the method implementation can work fine with mutable collections.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added this in 2b4de2d.
|
||
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. | ||
|
||
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds like "keep using scala.Seq
" should be the safe and simple option. I'd argue it's the opposite (unless your code happens to just work out of the box). In a complex codebase the simplest way forward is to change all references from scala.Seq
to scala.collection.Seq
and possibly insert toSeq
calls where necessary. This is easy to do and will cross-compile on 2.12 without any changes in semantics.
Switching your own codebase from scala.collection.Seq
to scala.immutable.Seq
is the more advanced refactoring. In many cases it may have been the intention all along, so it makes sense to do it. It also avoids unnecessary copying when varargs are involved, but it's much harder to get right consistently in a large codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. I'll mention recommendation to use scala.collection.Seq first then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added this in 2b4de2d.
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. | ||
|
||
- if you cross build with Scala 2.12 and want to maintain the API semantics for 2.13 version of your library, or | ||
- if your library users frequently uses mutable collections such as `Array` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If code has been optimized to the point that you build an array instead of a regular collection, you're probably okay calling unsafeWrapArray
, so it will still work with immutable varargs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Arrays might come up simply as Java API that you provide as a subset of API.
|
||
### Masking scala.Seq | ||
|
||
To use the compiler to bad the use of plain `Seq`, you can declare your own `Seq` to mask `scala.Seq`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/bad/ban/
- if you cross build with Scala 2.12 and want to maintain the API semantics for 2.13 version of your library, or | ||
- if your library users frequently uses mutable collections such as `Array` | ||
|
||
you can import collection Seq explicitly in your code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"import collection Seq" looks weird and kind of ambiguous.
No description provided.