-
Notifications
You must be signed in to change notification settings - Fork 87
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
Reconsider package names #331
Comments
just for reference, I put |
Thanks for digging these out, I didn't remember. My brain seems to be suppressing all memories of OSGi related work. |
Lukas and I discussed this last week. iirc, we sadly concluded that using a different artifact name doesn't make binary breaking changes harmless, and bumping the version number to 3.0.0 doesn't make them harmless, either. In order not to send any users to dependency hell, we must either:
Lukas, is that an accurate summary of our discussion? Option 2 seems hairy and not-worth-it to me. I'm certainly not eager to tackle it, it will annoy and confuse users, and it's not clear to me that the benefit is so great, anyway. 98% of Scala OSS has already added 2.13 to their crossbuilds, so there is value in just leaving things alone. So I suggest we go with option 1. That would mean:
wdyt? |
Changing the artifact name will potentially cause issues even with the proposed solution here. Due to transitive dependencies, one may end up with both in the classpath resulting in NoSuchMethodErrors if the newer version was used in compilation while the older version was used at runtime. Do we want to revert the artifact name change perhaps? |
Yeah... Seth said
That prevents classes from evolving. Let's say there's
in scala-collection-compat, and that it evolves to
in scala-library-compat. If it was the same module, sbt would pick the newest version. But with a different artifact name, both end up on the classpath, and behavior depends on which classfile is loaded first by scalac (compile-time) and the JVM (run-time). Also moving a class (
now
This is not binary compatible So I only see two ways forward
Before we decide to go back, I'd like to convince myself that breaking binary compatibility once is really not an option. The thing is, the compat library has great potential because the Scala 2.13 standard library is locked down by the forwards binary compatibility constraint. Scala 2.13 will have a very very long lifetime and 3.0 is planned to use the 2.13 library too. The compat library allows extending the standard library during that time. It's quite unfortunate that we have to explain to all users "for historical reasons, this library has a weird name and the package structure is inconsistent". Do we have a chance to find the direct users of scala-collection-compat and somehow make a coordinated effort to move everyone to the new artifact that breaks bin compat? |
Maybe one solution to rename the artifact without ending up with two artifacts in the classpath, would be to keep That doesn’t solve the question of breaking binary compatibility or not, though… |
Maybe the library for extending 2.13/3.0 could be
|
In the end, I don't think breaking binary compatibility is an option. Browsing through GitHub search, the library is used too widely, and fixing dependency conflicts will be too hard for users (figure out which of their depdendencies is built against an old collection-compat, check if there's a new version, ping maintainers, etc). So the packages have to remain what they are; as Seth said
For changing the artifact name, Julien's idea sounds plausible to me (but we'd have to do some testing). So we could release a new About including new classes for 2.13, we can either do it in this library, or in a completely new one. I'm fine either way. The 2.13 artifacts of To summarize, let's vote on these options (please comment for feedback / other suggestions):
If we pick 😄 or 🎉, we can at any point start a new library |
Feels viable to teach Scala Steward this, at worst non-generically. |
IMO, for maximum ease, we should keep the new
something about that doesn't sound right to me. the "outer" dependency (i.e. the one that depends on the other) needs to be the one that's empty. so either |
Why would that make things easier? Dependency resolution systems (e.g., coursier) will consider anyway that the two artifacts,
Right, good catch! My initial proposal was to keep the content of |
my thought was that it makes it easier for the end user to switch from the "deprecated" |
I thought some of the new stuff had already been released in |
Looking at the changelog and Git history, it seems that the content not related to collections has not been released yet, so we still have a chance to move it to a separate artifact. |
regarding |
except for |
That might make things more confusing, I feel that it's better to keep all classes in the same artifact. The standard library also doesn't have a split between collections and the rest. |
In that case, I think we should make |
Have we thought about transitive dependency situations? Say I depend on |
It seems like Maven has something for changing group ids, not sure if it also works with artifact ids: http://maven.apache.org/guides/mini/guide-relocation.html The discussion linked from that page seems to indicate that it's under-tested though. |
sbt would emit an eviction warning if there is a transitive dependencies conflict. |
That's good for SBT users. Thoughts on Maven and Gradle? |
I don't really use them so I'm not an expert, but dependency conflicts are not specific to this artifact, so I'm sure a solution exists. maybe the enforcer plugin for Maven? not sure |
It does, but it's routinely ignored because there are so many totally inconsequential ones in projects that aren't extremely close to the upstreamiest of upstreams. IME this only really surfaces once you get a NoSuchMethodError (or similar) at runtime. |
The vote is 2-2-2 so far. But it's 4:2 against using this library for new 2.13 additions. So if it continues to be a backports-only library, I'm really in favor of keeping the old name. Sure, it's a bit confusing, but we can explain. And it avoids messing with empty or split artifacts, introducing a faux dependency, wondering what will happen on various build tools, explaining why there are two artifacts. The usage of this library will fade out over time (when people migrate off 2.12). |
Good call. |
I don't understand all the in and outs of this discussion but would like to add a few points.
Overall, this is so good I can't imagine that it can't continue until the point it is not need via Tasty or whatever. |
I reallllly wanted the new name, as evidenced by my premature renaming of the repository, but after reading through all this discussion, I must regretfully conclude that it isn't worth the weirdness and trouble, so we should go back to scala-collection-compat :-( And we have consensus that scala-library-future will be separate. |
I would like to just depend on |
should we create a |
Also make clear that |
I renamed the repo back to scala-collection-compat, and I'm working on merging open PRs and publishing. I will make the scala-library-future repo soon. (We don't need to decide on the final name until it's time to publishing. The new repo will include a ticket to talk about the name. I'm thinking maybe scala-library-next would be less ambiguous.) |
💯 We definitely need a separate module just for Iterators. They are so hard to get right. Calling it |
|
Now that we change the artifact name, there's an opportunity to do binary breaking changes. (Though maybe it's a bad idea, and we should only consider it when we release a 3.0.0.)
In particular, I'm thinking of the inconsistency in the packages used for backported library classes, for example
scala.collection.compat.immutable.LazyList
, vsscala.util.Using
I assume the motivation to put
LazyList
in acompat
sub-package was to avoid split packages, i.e., to ensure that this module doesn't add any classes into packages that exist in the 2.11 / 2.12 standard library? Since it's not done consistently I think we should just use the original package name for backports (likescala.util.Using
does).A small but maybe still realistic issue is that the recommended
import scala.collection.compat._
brings animmutable
into scope which is notscala.collection.immutable
.The
scala.collection.compat
package object still makes sense for extension methods (import scala.collection.compat._; xs.to(List)
). Though, given that this is nowlibrary-compat
, should it just bescala.compat._
instead? There might be backports of non-collection extension methods in the future. I'm not sure.The text was updated successfully, but these errors were encountered: