Skip to content
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

Updates to the page on binary compatibility #3013

Merged
merged 1 commit into from
May 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions _overviews/core/binary-compatibility-of-scala-releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,25 @@ Note that for Scala.js and Scala Native, binary compatibility issues result in e
They happen during their respective "linking" phases: `{fast,full}LinkJS` for Scala.js and `nativeLink` for Scala Native.

#### Forward and Back
We distinguish forward and backward compatibility (think of these as properties of a sequence of versions, not of an individual version). Maintaining backwards compatibility means code compiled on an older version will link with code compiled with newer ones. Forward compatibility allows you to compile on new versions and run on older ones.
We distinguish forward and backward compatibility (think of these as properties of a sequence of versions, not of an individual version). Maintaining backward compatibility means code compiled on an older version will link with code compiled with newer ones. Forward compatibility allows you to compile on new versions and run on older ones.

Thus, backwards compatibility precludes the removal of (non-private) methods, as older versions could call them, not knowing they would be removed, whereas forwards compatibility disallows adding new (non-private) methods, because newer programs may come to depend on them, which would prevent them from running on older versions (private methods are exempted here as well, as their definition and call sites must be in the same compilation unit).
Thus, backward compatibility precludes the removal of (non-private) methods, as older versions could call them, not knowing they would be removed, whereas forward compatibility disallows adding new (non-private) methods, because newer programs may come to depend on them, which would prevent them from running on older versions (private methods are exempted here as well, as their definition and call sites must be in the same source file).

#### Guarantees and Versioning
For Scala 2, the *minor* version is the *third* number in a version, e.g., 10 in v2.13.10.
The major version is the second number, which is 13 in our example.

Scala 2 guarantees both backward and forward compatibility across *minor* releases within a single major release.

These are strict constraints, but they have worked well for us since Scala 2.10.x.
They didn't stop us from fixing large numbers of issues in minor releases.
So far, that policy is still applicable for Scala 2, although [there exists a proposal to remove the forward compatibility guarantee](https://docs.scala-lang.org/sips/drop-stdlib-forwards-bin-compat.html).
Scala 2 up to 2.13.14 guarantees both backward and forward compatibility across *minor* releases within a single major release.
This is about to change now that [SIP-51 has been accepted](https://docs.scala-lang.org/sips/drop-stdlib-forwards-bin-compat.html), future Scala 2.13 releases may be backward compatible only.

For Scala 3, the minor version is the *second* number in a version, e.g., 2 in v3.2.1.
The third number is the *patch* version.
The major version is always 3.

Scala 3 guarantees both backward and forward compatibility across *patch* releases within a single minor release.
In particular, this applies within an entire [Long-Term-Support (LTS) series](https://www.scala-lang.org/blog/2022/08/17/long-term-compatibility-plans.html) (which will start with Scala 3.3.x).
Scala 3 guarantees both backward and forward compatibility across *patch* releases within a single minor release (enforcing forward binary compatibility is helpful to maintain source compatibility).
In particular, this applies within an entire [Long-Term-Support (LTS) series](https://www.scala-lang.org/blog/2022/08/17/long-term-compatibility-plans.html) such as Scala 3.3.x.

It also guarantees *backward* compatibility across *minor* releases in the entire 3.x series, but not forward compatibility.
Scala 3 also guarantees *backward* compatibility across *minor* releases in the entire 3.x series, but not forward compatibility.
This means that libraries compiled with any Scala 3.x version can be used in projects compiled with any Scala 3.y version with y >= x.

In addition, Scala 3.x provides backward binary compatibility with respect to Scala 2.13.y.
Expand Down Expand Up @@ -72,8 +69,8 @@ At this point, you are likely going to run into bugs.
Please report issues you find to its issue tracker.

#### Concretely
We guarantee forwards and backwards compatibility of the `"org.scala-lang" % "scala-library" % "2.N.x"` and `"org.scala-lang" % "scala-reflect" % "2.N.x"` artifacts, except for
- the `scala.reflect.internal` and `scala.reflect.io` packages, as scala-reflect is still experimental, and
We guarantee backward compatibility of the `"org.scala-lang" % "scala-library" % "2.N.x"` and `"org.scala-lang" % "scala-reflect" % "2.N.x"` artifacts, except for
- the `scala.reflect.internal` and `scala.reflect.io` packages, as scala-reflect is experimental, and
- the `scala.runtime` package, which contains classes used by generated code at runtime.

We also strongly discourage relying on the stability of `scala.concurrent.impl`, `scala.sys.process.*Impl`, and `scala.reflect.runtime`, though we will only break compatibility for severe bugs here.
Expand All @@ -83,4 +80,7 @@ Forward compatibility is only guaranteed for `3.N.y` within a given `N`.

We enforce *backward* (but not forward) binary compatibility for *modules* (artifacts under the groupId `org.scala-lang.modules`). As they are opt-in, it's less of a burden to require having the latest version on the classpath. (Without forward compatibility, the latest version of the artifact must be on the run-time classpath to avoid linkage errors.)

Finally, from Scala 2.11 until Scala 2.13.0-M1, `scala-library-all` aggregates all modules that constitute a Scala release. Note that this means it does not provide forward binary compatibility, whereas the core `scala-library` artifact does. We consider the versions of the modules that `"scala-library-all" % "2.N.x"` depends on to be the canonical ones, that are part of the official Scala distribution. (The distribution itself is defined by the `scala-dist` maven artifact.)
#### Build Tools
Build tools like sbt and mill have assumptions about backward binary compatibility built in.
They build a graph of a project's dependencies and select the most recent versions that are needed.
To learn more, see the page on [library dependencies](https://www.scala-sbt.org/1.x/docs/Library-Dependencies.html) in the sbt documentation.
Loading