I've long thought that sbt having two notations for setting keys, one for sbt shell and another for
build.sbt made the tool harder to learn.
As a recap:
- in sbt shell the full form of the scoped key is written as
- in build.sbt, it's written as
key in (proj, Config, intask)
Recently I've implemented two solutions for unifying the notation.
solution 1: Unified slash syntax
First implementation is actually a third syntax that can be used for both the shell and build.sbt. Instead of
::, the slash syntax uses
/ for all levels.
> Global / cancelable
> ThisBuild / scalaVersion
> Test / test
> root / Compile / compile / scalacOptions
In build.sbt it would look like this:
lazy val root = (project in file("."))
Global / cancelable := true,
ThisBuild / scalaVersion := "2.12.2",
Test / test := (),
Compile / console / scalacOptions += "-Ywarn-numeric-widen"
solution 2: Unify to build.sbt DSL
Second implementation is unifying towards the current build.sbt DSL. This accepts the use of
key in (proj, Config, intask) notation in sbt shell:
> cancelable in Global
> test in Test
> scalacOptions in (root, Compile, compile)
> scalacOptions in root in Compile in compile
In both solutions, the String representation of scoped keys in commands such as
inspect should work both both the shell and
Another interesting thing to note is that both the slash syntax and build.sbt parser can overlay on top of the existing 0.13 (
<project-id>/config:intask::key) shell. As demonstrated by the fact that I first sent the PR to 0.13 branch, keeping the old shell notation around or not is another knob we can tweak.
Now that there are two solutions, the question is which one is better.
@sjrd has argued against the slash syntax:
The mere fact of changing the syntax will have dramatic consequences on the eco-system.
... The last time we had a change of syntax was in sbt 0.13, 4 years ago, we and are still paying the price of changing that syntax, because there is so much documentation and SO answers out there using the old syntax. ...
If we're going to unify the syntaxes of the REPL and .sbt files, I would suggest we don't touch the syntax of .sbt files, and instead only adapt the syntax of the REPL to be the same.
@lihaoyi is in favor of the slash syntax over build.sbt:
I personally prefer the slash syntax to the build.sbt syntax.
... If we believe that the 0.13 syntax is the problem, rather than the rate-of-change of syntax, then the correct thing to do isn't to avoid further change but rather to evolve away from the problematic parts of 0.13 syntax as fast as possible.
What are your thoughts? Which solution do you think will reduce the cognitive load of learning sbt?