Skip to content

Commit 1dc49fe

Browse files
committed
Fix typos according to review
1 parent 3579e55 commit 1dc49fe

File tree

1 file changed

+10
-12
lines changed

1 file changed

+10
-12
lines changed

blog/_posts/2021-02-16-improving-scala-library-ecosystem.md

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ by: Eugene Yokota, Julien Richard-Foy
55
title: Improving the Scala Library Ecosystem
66
---
77

8-
One of the things that makes Scala powerful and fun to use is its library ecosystem — spanning across the Maven ecosystem for JVM, and npm for Scala.JS. We can use libraries to do operations like download files from the web, or we can use it to adopt different programming paradigms. The library ecosystem allows us to write more useful programs with less effort.
9-
10-
## What is a version conflict?
8+
One of the things that makes Scala powerful and fun to use is its library ecosystem — spanning across the Maven ecosystem for JVM, and npm for Scala.js. We can use libraries to do operations like download files from the web, or we can use it to adopt different programming paradigms. The library ecosystem allows us to write more useful programs with less effort.
119

1210
However, the library ecosystem is not without problems. A library that you pulled could depend on other libraries, and the transitive dependencies could cause version conflicts. Here's a quick example of a Scala project that uses Akka HTTP, a Postgres database, and JSON. Its build declares two library dependencies, `akka-http-circe` and `doobie-postgres-circe`:
1311

@@ -32,15 +30,15 @@ What happens here is that one of the transitive dependencies of `akka-http-circe
3230
[info] +-io.circe:circe-core_2.12:0.13.0 [S]
3331
~~~
3432

35-
Unfortunately, these two versions of Circe are not binary compatible. Such version conflicts are inevitable in a dependency graph of any practical size. The problem is that we carefully program our code using a statically checked type system, but when it comes to production code we accept swapping out the JAR file with something that our dependency resolver like Coursier and Apache Ivy selected on a whim.
33+
Unfortunately, these two versions of Circe are not binary compatible. Such version conflicts are common in a dependency graph of any practical size. The problem is that we carefully program our code using a statically checked type system, but when it comes to production code we accept swapping out the JAR file with something that our dependency resolver like Coursier and Apache Ivy selected on a whim.
3634

37-
Scala Center, Alexandre Archambault (author of Coursier), and I (Eugene Yokota) have been working on a solution to improve this situation so we can be confident about creating libraries, and using them.
35+
The Scala Center, Alexandre Archambault (author of Coursier), and Eugene Yokota have been working on a solution to improve this situation so that we can be confident about creating libraries, and using them.
3836

39-
In the next section, I will explain the mechanism that was in place so far in sbt to address this issue, and I will discuss its limits. Then, I will introduce a new solution, which concerns both library authors, and library users.
37+
In the next section, we will explain the mechanism that was in place so far in sbt to address this issue, and we will discuss its limits. Then, we will introduce a new solution, which concerns both library authors, and library users.
4038

4139
## Eviction warnings
4240

43-
Actually this is not the first time I've thought of this issue. In 2014, I added [eviction warning][1] feature to sbt 0.13.6. In the lingo of dependency resolver, when you have two candidate versions 0.11.1 and 0.13.0, and when it picks 0.13.0, 0.11.1 is said to be evicted.
41+
Actually this is not the first time We have thought of this issue. In 2014, we added [eviction warning][1] feature to sbt 0.13.6. When you have two candidate versions 0.11.1 and 0.13.0, and when it picks 0.13.0, 0.11.1 is said to be "evicted".
4442

4543
~~~ text
4644
sbt:killer-app> evicted
@@ -53,7 +51,7 @@ sbt:killer-app> evicted
5351

5452
Here, we see that sbt successfully detected the conflict for circe-core.
5553

56-
This was a step in the right direction, but it did not work well in reality because I had no way to tell whether two versions of a library would be binary compatible or not. In 2014 what I did was guess that a Java library would adopt [Semantic Versioning][2], and a Scala library would adopt [PVP][3]. (Apparently, using the first two numbers of the version, e.g. 1.2.x, to mean major version has a name, and it's Haskell Package Versioning Policy, or PVP for short).
54+
This was a step in the right direction, but it did not work well in reality because we had no way to tell whether two versions of a library would be binary compatible or not. In 2014 what we did was guess that a Java library would adopt [Semantic Versioning][2], and a Scala library would adopt [PVP][3]. (Apparently, the versioning scheme “epoch.major.minor” has a name, and it is Haskell Package Versioning Policy, or PVP for short).
5755

5856
Unfortunately, the reality was different and while some Scala libraries use PVP (e.g., Play framework, the standard library, …), some others do use Semantic Versioning (e.g., `scala-collection-compat`, `cats`, …). This makes eviction warnings less reliable since many of these warnings are false positive, and, in practice, [they are ignored by developers][7].
5957

@@ -69,9 +67,9 @@ Given a version number `major.minor.patch`, you MUST increment the:
6967

7068
- When the `major` version is `0`, a minor version increment MAY contain **both source and binary breakages**, but a patch version increment MUST remain **binary compatible**.
7169

72-
We call this Early SemVer, because according to the [Semantic Versioning Spec][2] there are no guarantees between any versions when the major version is `0`. In the Scala library ecosystem, though, we often start guaranteeing binary compatibility for `0.y.z` like sbt 0.13 and Scala.JS 0.6.
70+
We call this Early SemVer, because according to the [Semantic Versioning Spec][2] there are no guarantees between any versions when the major version is `0`. In the Scala library ecosystem, though, we often start guaranteeing binary compatibility for `0.y.z` like sbt 0.13 and Scala.js 0.6.
7371

74-
Unfortunately, it is not an easy task to know whether a change on public API broke source or binary compatibility. Scala Center contracted Alexandre Archambault to create [sbt-version-policy][5]. This plugin helps library authors to self-check a version scheme. To use this, add the following to your `project/plugins.sbt`:
72+
Unfortunately, it is not an easy task to know whether a change on public API broke source or binary compatibility. The Scala Center contracted Alexandre Archambault to create [sbt-version-policy][5]. This plugin helps library authors to self-check a version scheme. To use this, add the following to your `project/plugins.sbt`:
7573

7674
~~~ scala
7775
addSbtPlugin("ch.epfl.scala" % "sbt-version-policy" % "1.0.0-RC5")
@@ -90,7 +88,7 @@ This plugin provides a task called `versionPolicyCheck`, which you can call in t
9088
> versionPolicyCheck
9189
~~~
9290

93-
I think Early Semver gives better flexibility to both library authors and library users since it gives more information about what would be in minor upgrades (I often call this feature release) vs patch. For example, sbt 1 ships bug fixes as 1.3.x patch releases without going through RC cycle, so bug fixes are released quickly.
91+
We think Early SemVer gives better flexibility to both library authors and library users since it gives more information about what would be in minor upgrades (we often call this feature release) vs patch. For example, sbt 1 ships bug fixes as 1.3.x patch releases without going through RC cycle, so bug fixes are released quickly.
9492

9593
During the minor upgrade (feature release), we aggressively add new features, while maintaining binary compatibility for the plugin ecosystem. These only come out once a year, and it goes through the RC cycle.
9694

@@ -116,7 +114,7 @@ ThisBuild / libraryDependencySchemes += "io.circe" %% "circe-*" % "early-semver"
116114

117115
## Summary
118116

119-
If you are a library author, check out [sbt-version-policy][5] to enforce the recommended versioning scheme. Or, at least declare the versioning scheme you use, with the `versionScheme` key. If you are a library user, keep in mind that starting from sbt 1.5.0 you should configure your `libraryDependencySchemes` to get accurate eviction errors.
117+
If you are a library author, check out [sbt-version-policy][5] to enforce the recommended versioning scheme. Or, at least declare the versioning scheme you use with the `versionScheme` key. If you are a library user, keep in mind that starting from sbt 1.5.0 you should configure your `libraryDependencySchemes` to get accurate eviction errors.
120118

121119
[1]: https://github.com/sbt/sbt/pull/147
122120
[2]: https://semver.org/

0 commit comments

Comments
 (0)