Equality in Scala
I gave a talk at ScalaMatsuri on ‘Equality in Scala’
I gave a talk at ScalaMatsuri on ‘Equality in Scala’
Hi everyone. On behalf of the sbt project, I am happy to announce sbt 1.4.0. This is the fourth feature release of sbt 1.x, a binary compatible release focusing on new features. sbt 1.x is released under Semantic Versioning, and the plugins are expected to work throughout the 1.x series.
The headline features of sbt 1.4.0 are:
ThisBuild / versionScheme to take the guessing out of eviction warningHi everyone. On behalf of the sbt project, I am happy to announce sbt 1.4.0-RC2. This is the fourth feature release of sbt 1.x, a binary compatible release focusing on new features. sbt 1.x is released under Semantic Versioning, and the plugins are expected to work throughout the 1.x series.
The headline features of sbt 1.4.0 are:
ThisBuild / versionScheme to take the guessing out of eviction warning
4h 29m
This is part 4 of the post about sbt-projectmatrix, an experimental plugin that I’ve been working to improve the cross building in sbt. Here’s part 1, part 2, and part 3. I’ve just released 0.6.0.
After adding sbt-projectmatrix to your build, here’s how you can set up a matrix with two Scala versions.
ThisBuild / organization := "com.example"
ThisBuild / scalaVersion := "2.12.12"
ThisBuild / version := "0.1.0-SNAPSHOT"
lazy val core = (projectMatrix in file("core"))
.settings(
name := "core"
)
.jvmPlatform(scalaVersions = Seq("2.12.12", "2.13.3"))
This will create subprojects for each scalaVersion. Unlike ++ style stateful cross building, these will build in parallel. This part has not changed.
I’m excited to announce that I’m joining Twitter’s Build Team to work on the next generation of efficient build systems supporting thousands of Twitter developers worldwide. Today’s my first day.
This is the team that developed monorepo build tool Pants, and is transitioning to migrate the flock to Bazel. This presented a unique opportunity for me to work with a team of people passionate about developer experience and productivity, and I’m looking forward to getting to know the team, and learning the new challenges.
I’m happy to announce sbt-buildinfo 0.10.0. sbt-buildinfo is a small sbt plugin to generate BuildInfo object from your build definitions.
Since the last feature release was in 2018, there have been some pending contributions. I think the important thing is that it compiles with -Xlint and -Xfatal-warnings on both Scala 2.13.3 and 2.12.12.
In this post, we’ll try to automate the release of an sbt plugin using Ólafur’s olafurpg/sbt-ci-release. The README of sbt-ci-release covers the use case for a library published to Sonatype OSS. Read it thoroughly since this post will skip over the details that do not change for publishing sbt plugins.
Automated release in general is a best practice, but there’s one benefit specifically for sbt plugin releases. Using this setup allows multiple people to share the authorization to release an sbt plugin without adding them to Bintray sbt organization. This is useful for plugins maintained at work.
Spotify: https://open.spotify.com/playlist/5BkvksBTbrngqXxhF6wUAc?si=Kj8TrnhRQICDTgadvYYt2w YouTube: https://www.youtube.com/playlist?list=PLSUh6oJ5ZotXfMWZPzm6K_L0CRPgFhxGh 2h 4m
I’m happy to announce sbt 1.3.13 patch release. Full release note is here - https://github.com/sbt/sbt/releases/tag/v1.3.13.
Special thanks to Scala Center. It takes time to review bug reports, pull requests, make sure contributions land to the right places, and Scala Center sponsored me to do maintainer tasks for sbt during June.
3h 59m
I’m happy to announce sbt 1.3.12 patch release. Full release note is here - https://github.com/sbt/sbt/releases/tag/v1.3.12.
Special thanks to Scala Center. It takes time to review bug reports, pull requests, make sure contributions land to the right places, and Scala Center sponsored me to do maintainer tasks for sbt during May. Darja + whole Scala Center crew have been chill to work with.
There was a regression in sbt 1.3.11 around the launcher integration, which showed up as repositories file getting ignored. sbt 1.3.12 fixes it. #5583
I’m happy to announce sbt 1.3.11 patch release. Full release note is here - https://github.com/sbt/sbt/releases/tag/v1.3.11.
Special thanks to Scala Center. It takes time to review bug reports, pull requests, make sure contributions land to the right places, and Scala Center sponsored me to do maintainer tasks for sbt during May. Darja + whole Scala Center crew have been chill to work with.
Normally changing the project/build.properties to
sbt.version=1.3.11
would be ok. However, given that the release may contain fixes to scripts and also because your initial resolution would be faster with *.(zip|tgz|msi) that contains all the JAR files, we recommend you use the installer distribution. They will be available from SDKMAN etc:
Jar Jar Abrams is an experimental Scala extension of Jar Jar Links, a utility to shade Java libraries.
For library authors, the idea of other library is a double-edged sword. On one hand, using other libraries avoids unnecessary duplication of work, not using other libraries is almost hypocritical. On the other hand, each library you add would add a transitive dependency to your users, increasing the possibility of conflict. This is partly due to the fact that within a single running program you can one have one version of a library.
In sbt core concepts talks I’ve been calling sbt a casually functional build tool. Two hallmarks of functional programming are that it uses immutable data structure instead of mutation, and that it gives attention to when and how effects are handled.
From this perspective, we can think of setting expressions and tasks to be those two things:
Anonymous settings are represented using Initialize[A], which looks like this:
build.sbt is a DSL for defining a task graph to be used for automatic parallel processing. The message passing among the tasks are expressed using something.value macro, which encodes Applicative composition (task1, task2) mapN { case (t1, t2) => .... }.
One mechanism I’ve been thinking about is allowing some long-running task1 to communicate with task2 midway.

Normally, we would break down task1 into two subtasks. But it might not be as straight-forward to implement such thing. For example, how would be tell Zinc to compile something halfway, and resume later? Or tell Coursier to resolve, but fetch later?
I’m happy to announce sbt 1.3.10 patch release. Full release note is here - https://github.com/sbt/sbt/releases/tag/v1.3.10
Normally changing the project/build.properties to
sbt.version=1.3.10
would be ok. However, given that the release may contain fixes to scripts and also because your initial resolution would be faster with *.(zip|tgz|msi) that contains all the JAR files, we recommend you use the installer distribution. They will be available from SDKMAN etc.
Homebrew maintainers have added a dependency to JDK 13 because they want to use more brew dependencies brew#50649. This causes sbt to use JDK 13 even when java available on PATH is JDK 8 or 11.
I’ve just released Zinc 1.4.0-M1. Note this is a beta release and it won’t be compatible with future 1.4.x, but I chose a commit fairly close to 1.3.x so it should be usable.
java.util.Date with java.time zinc#714 by @slandelleZinc is an incremental compiler for Scala. Though Zinc is capable of compiling Scala 2.10 ~ 2.13 and Dotty, thus far Zinc itself has been implemented using Scala 2.12. This is fine for sbt 1.x, which is also implemented in Scala 2.12, but there’s been requests to cross build Zinc for 2.13.
This is part 3 of the post about sbt-projectmatrix, an experimental plugin that I’ve been working to improve the cross building in sbt. Here’s part 1 and part 2. I’ve just released 0.5.0.
After adding sbt-projectmatrix to your build, here’s how you can set up a matrix with two Scala versions.
ThisBuild / organization := "com.example"
ThisBuild / scalaVersion := "2.12.10"
ThisBuild / version := "0.1.0-SNAPSHOT"
lazy val core = (projectMatrix in file("core"))
.settings(
name := "core"
)
.jvmPlatform(scalaVersions = Seq("2.12.10", "2.11.12"))
This will create subprojects coreJVM2_11 and coreJVM2_12. Unlike ++ style stateful cross building, these will build in parallel. This part has not changed.
I joined Lightbend (then Typesafe) in March, 2014. After six incredible years April 7, 2020 was my last day. I am grateful that I got the opportunity to work with an amazing group of people at Lightbend, partners, customers, and various people I got to meet at conferences. Looking back, before COVID-19 times, it’s almost surreal that I was flying to Europe, Asia, and North America every few months to attend conferences and tech meetings.
Last week I wrote about #8820, my proposal to add user-land compiler warnings in Scala. The example I had was implementing ApiMayChange annotation.
package foo
import scala.annotation.apiStatus, apiStatus._
@apiStatus(
"should DSL is incubating, and future compatibility is not guaranteed",
category = Category.ApiMayChange,
since = "foo-lib 1.0",
defaultAction = Action.Warning,
)
implicit class ShouldDSL(s: String) {
def should(o: String): Unit = ()
}
This was ok as a start, but a bit verbose. If we want some API status to be used frequently, it would be cool if library authors could define their own status annotation. We’re going to look into doing that today.
serves 4?
put cold water in a large dutch oven with 5 dried shiitake and similar amount of dried kombu kelp. let it sit for a few hours covered.

As a library author, I’ve been wanting to tag methods in Scala that can trigger custom warnings or compiler errors. Why would I want to intentionally cause a compiler error? One potential use case is displaying a migration message for a removed API.
Restligeist macro: n. A macro that fails immediately to display migration message after implementation has been removed from the API.
— ∃ugene yokot∀ (@eed3si9n) August 30, 2016
For example, if you try to use <<= in sbt 1.3.8 you’d get the following error on load:
4h 35m
The relationship given to Int and Long should be exactly the same as the relationship third-party library like Spire can write UInt or Rational with the first-class numeric types.
1 == 1L an error under strictEqualityFromDigitsI want to understand how equality works in Scala. It’s a complicated topic that’s been going on for ten years.
Major concerns are:
nullF[+A])Understanding equality means knowing how these combinations are compared.
The language spec provides some hints, although it does not have the full information. Chapter 12 contains the definition of Any as follows:
I added a small app called giter8-launcher for Giter8 0.12.0. The purpose of the app is to make the behavior of the Giter8 template more predictable. Today, template authors may create a template for some version of Giter8 X, but the users might use some other version of Giter8 Y that ships with “sbt new.”
One of the neat ideas about sbt is that no matter what version of sbt script users might have it installed, the core sbt version is specified by the build author using project/build.properties file. This significantly reduces the it-only-works-on-my-machine problem. giter8-launcher is analogous to sbt’s sbt-launcher. giter8-launcher clones the template and reads project/build.properties file to determine the Giter8 version to render the template.
Template authors can now specify the Giter8 version in project/build.properties file as:
giter8.version=0.12.0
3h 38m