Mike Slinn
Mike Slinn

Disappointing Scala 3 Installation Experience

Published 2021-05-19. Last modified 2021-05-21.
Time to read: about 2 minutes.

This article is categorized under Scala.

I run ScalaCourses.com, an online Scala training web site. After years of hype, Scala 3 is now available.

Scala 3: Not Yet Ready for Production

Scala 3 was eight years in the making. You would never know that from the horrible installation process and the disappointing installation instructions.

It is going to take quite a while before Scala 3, which was known as Dotty before it was released, can be trusted in production. According to the Dotty GitHub project, the only published future milestone is v3.1.0, which has no due date. Given that Scala 3 uses an entirely new build process, and an entirely new (and nonstandard) installation process, and that the internals of the Scala compiler were almost completely replaced, I doubt that version will be stable enough for use on production projects.

Installation Choices

Installation cholices include:

  • Command-line Scala has limited use cases, but is nice to have around for occassional experimentation.
  • SBT (which features an enhanced Scala REPL) is very helpful for interactively developing code, as well as for building and testing.
  • IntelliJ provides the best Scala coding productivity and code quality.
  • VSCode has been playing catch-up but is not full-featured yet.

Installation Transcript

The following is the transcript of how I installed command-line Scala on Ubuntu 20.10 running under WSL2.

Remove Scala 2

This step is not required. Scala 2 and Scala 3 can easily co-exist on the same system because their names are different.

Shell
$ sudo apt remove scala
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be REMOVED:
  scala
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 666 MB disk space will be freed.
Do you want to continue? [Y/n]
(Reading database ... 236024 files and directories currently installed.)
Removing scala (2.13.4-400) ...
Processing triggers for man-db (2.9.3-2) ... 

Install Coursier

Coursier is a multithreaded downloader for project dependencies, and it now also downloads Scala 3. SBT uses coursier internally.

Shell
$ curl -fLo cs https://git.io/coursier-cli-"$(uname | tr LD ld)"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100   144  100   144    0     0    285      0 --:--:-- --:--:-- --:--:--  6000
100 57.1M  100 57.1M    0     0  3656k      0  0:00:15  0:00:15 --:--:-- 4092k 

$ mv cs ~/.local/bin/

$ chmod a+x ~/.local/bin/cs

$ cs install cs
https://repo1.maven.org/maven2/io/get-coursier/apps/maven-metadata.xml
  100.0% [##########] 1.8 KiB (8.5 KiB / s)
https://repo1.maven.org/maven2/io/get-coursier/coursier-cli_2.12/maven-metadata.xml
  No new update since 2021-03-23 14:35:16
Wrote cs
Warning: /home/mslinn/.local/share/coursier/bin is not in your PATH
To fix that, add the following line to ~/.bashrc

export PATH="$PATH:/home/mslinn/.local/share/coursier/bin" 

$  export PATH="$PATH:/home/mslinn/.local/share/coursier/bin"

Now let's test Coursier:

Shell
$ cs
Coursier 2.0.16
Usage: cs [options] [command] [command-options]

Available commands: bootstrap, channel, complete, fetch, get, install, java, java-home, launch, list, publish, resolve, setup, uninstall, update, search

Type  cs command --help  for help on an individual command 

This is the Coursier help message for the install subcommand:

Shell
$ cs install --help
Command: install
Usage: cs install
--cache  <string?>
Cache directory (defaults to environment variable COURSIER_CACHE, or ~/.cache/coursier/v1 on Linux and ~/Library/Caches/Coursier/v1 on Mac)
--mode | -m  <offline|update-changing|update|missing|force>
Download mode (default: missing, that is fetch things missing from cache)
--ttl | -l  <duration>
TTL duration (e.g. "24 hours")
--parallel | -n  <int>
Maximum number of parallel downloads (default: 6)
--checksum  <checksum1,checksum2,...>
Checksum types to check - end with none to allow for no checksum validation if no checksum is available, example: SHA-256,SHA-1,none
--retry-count  <int>
Retry limit for Checksum error when fetching a file
--cache-file-artifacts | --cfa  <bool>
Flag that specifies if a local artifact should be cached.
--follow-http-to-https-redirect  <bool>
Whether to follow http to https redirections
--credentials  <host(realm) user:pass|host user:pass>
Credentials to be used when fetching metadata or artifacts. Specify multiple times to pass multiple credentials. Alternatively, use the COURSIER_CREDENTIALS environment variable
--credential-file  <string*>
Path to credential files to read credentials from
--use-env-credentials  <bool>
Whether to read credentials from COURSIER_CREDENTIALS (env) or coursier.credentials (Java property), along those passed with --credentials and --credential-file
--quiet | -q  <counter>
Quiet output
--verbose | -v  <counter>
Increase verbosity (specify several times to increase more)
--progress | -P  <bool>
Force display of progress bars
--log-changing  <bool>
Log changing artifacts
--log-channel-version | --log-index-version | --log-jvm-index-version  <bool>
Log app channel or JVM index version
--graalvm-home  <string?>
--graalvm-option  <string*>
--graalvm-default-version  <string?>
--install-dir | --dir  <string?>
--install-platform  <string?>
Platform for prebuilt binaries (e.g. "x86_64-pc-linux", "x86_64-apple-darwin", "x86_64-pc-win32")
--install-prefer-prebuilt  <bool>
--only-prebuilt  <bool>
Require prebuilt artifacts for native applications, don't try to build native executable ourselves
--repository | -r  <maven|sonatype:$repo|ivy2local|bintray:$org/$repo|bintray-ivy:$org/$repo|typesafe:ivy-$repo|typesafe:$repo|sbt-plugin:$repo|ivy:$pattern>
Repository - for multiple repositories, separate with comma and/or add this option multiple times (e.g. -r central,ivy2local -r sonatype:snapshots, or equivalently -r central,ivy2local,sonatype:snapshots)
--default-repositories  <bool>
--proguarded  <bool?>
--channel  <org:name>
Channel for apps
--default-channels  <bool>
Add default channels
--contrib  <bool>
Add contrib channel
--file-channels  <bool>
Add channels read from the configuration directory
--jvm  <string?>
--jvm-dir  <string?>
--system-jvm  <bool?>
--local-only  <bool>
--update  <bool>
--jvm-index  <string?>
--repository | -r  <maven|sonatype:$repo|ivy2local|bintray:$org/$repo|bintray-ivy:$org/$repo|typesafe:ivy-$repo|typesafe:$repo|sbt-plugin:$repo|scala-integration|scala-nightlies|ivy:$pattern|jitpack|clojars|jcenter|apache:$repo>
Repository - for multiple repositories, separate with comma and/or add this option multiple times (e.g. -r central,ivy2local -r sonatype:snapshots, or equivalently -r central,ivy2local,sonatype:snapshots)
--no-default  <bool>
Do not add default repositories (~/.ivy2/local, and Central)
--sbt-plugin-hack  <bool>
Modify names in Maven repository paths for sbt plugins
--drop-info-attr  <bool>
Drop module attributes starting with 'info.' - these are sometimes used by projects built with sbt
--channel  <org:name>
Channel for apps
--default-channels  <bool>
Add default channels
--contrib  <bool>
Add contrib channel
--file-channels  <bool>
Add channels read from the configuration directory
--repository | -r  <maven|sonatype:$repo|ivy2local|bintray:$org/$repo|bintray-ivy:$org/$repo|typesafe:ivy-$repo|typesafe:$repo|sbt-plugin:$repo|scala-integration|scala-nightlies|ivy:$pattern|jitpack|clojars|jcenter|apache:$repo>
Repository - for multiple repositories, separate with comma and/or add this option multiple times (e.g. -r central,ivy2local -r sonatype:snapshots, or equivalently -r central,ivy2local,sonatype:snapshots)
--no-default  <bool>
Do not add default repositories (~/.ivy2/local, and Central)
--sbt-plugin-hack  <bool>
Modify names in Maven repository paths for sbt plugins
--drop-info-attr  <bool>
Drop module attributes starting with 'info.' - these are sometimes used by projects built with sbt
--channel  <org:name>
Channel for apps
--default-channels  <bool>
Add default channels
--contrib  <bool>
Add contrib channel
--file-channels  <bool>
Add channels read from the configuration directory
--env  <bool>
--disable-env | --disable  <bool>
--setup  <bool>
--user-home  <string?>
--add-channel  <string*>
(deprecated)
--force | -f  <bool> 

Install Scala 3

The Scala 3 compiler and REPL are separate programs: scala3-compiler and scala3-repl.

Shell
$ cs install scala3-compiler
https://repo1.maven.org/maven2/org/scala-lang/scala3-compiler_3/3.0.0/scala3-compiler_3-3.0.0.pom
  100.0% [##########] 4.8 KiB (79.7 KiB / s)
https://repo1.maven.org/maven2/org/scala-lang/tasty-core_3/3.0.0/tasty-core_3-3.0.0.pom
  100.0% [##########] 3.5 KiB (69.5 KiB / s)
https://repo1.maven.org/maven2/org/scala-lang/scala3-library_3/3.0.0/scala3-library_3-3.0.0.pom
  100.0% [##########] 3.6 KiB (53.9 KiB / s)
https://repo1.maven.org/maven2/org/scala-lang/scala3-interfaces/3.0.0/scala3-interfaces-3.0.0.pom
  100.0% [##########] 3.4 KiB (65.9 KiB / s)
https://repo1.maven.org/maven2/org/scala-lang/scala3-interfaces/3.0.0/scala3-interfaces-3.0.0.jar
  100.0% [##########] 3.4 KiB (113.9 KiB / s)
https://repo1.maven.org/maven2/org/scala-lang/tasty-core_3/3.0.0/tasty-core_3-3.0.0.jar
  100.0% [##########] 71.9 KiB (192.7 KiB / s)
https://repo1.maven.org/maven2/org/scala-lang/scala3-library_3/3.0.0/scala3-library_3-3.0.0.jar
  100.0% [##########] 1.1 MiB (1.8 MiB / s)
https://repo1.maven.org/maven2/org/scala-lang/scala3-compiler_3/3.0.0/scala3-compiler_3-3.0.0.jar
  100.0% [##########] 14.7 MiB (3.7 MiB / s)
Wrote scala3-compiler 

$ cs install scala3-repl
https://repo1.maven.org/maven2/io/get-coursier/apps/maven-metadata.xml
  No new update since 2021-05-14 04:42:19
Wrote scala3-repl 

Run Scala 3 REPL

The part is easy!

Shell
$ scala3-repl --version
Scala code runner version 3.0.0 -- Copyright 2002-2021, LAMP/EPFL 

$ scala3-repl
scala> 

Easily Run Scala REPL With SBT

If you do not mind directories called project/ and target/ being created in your current directory, and you have already installed sbt, you can get a REPL powered by Scala 3 like this:

Shell
$ sbt "-Dsbt.version=1.5.2" ++3.0.0! console
[info] welcome to sbt 1.5.2 (Ubuntu Java 11.0.11)
  [info] loading global plugins from /home/mslinn/.sbt/1.0/plugins
  [info] loading project definition from /var/work/ancientWarmth/ancientWarmth/project
  [info] set current project to ancientwarmth (in build file:/var/work/ancientWarmth/ancientWarmth/)
  [info] Forcing Scala version to 3.0.0 on all projects.
  [info] Reapplying settings...
  [info] set current project to ancientwarmth (in build file:/var/work/ancientWarmth/ancientWarmth/)
  [info] Updating
  [info] Resolved  dependencies
  [info] Updating
  https://repo1.maven.org/maven2/org/scala-lang/scaladoc_3/3.0.0/scaladoc_3-3.0.0.pom
    100.0% [##########] 6.1 KiB (82.6 KiB / s)
  https://repo1.maven.org/maven2/org/scala-lang/scala3-tasty-inspector_3/3.0.0/scala3-tasty-inspector_3-3.0.0.pom
    100.0% [##########] 3.6 KiB (80.8 KiB / s)
  [info] Resolved  dependencies
  [info] Fetching artifacts of
  [info] Fetched artifacts of
  [info] Fetching artifacts of
  https://repo1.maven.org/maven2/org/scala-lang/scala3-tasty-inspector_3/3.0.0/scala3-tasty-inspector_3-3.0.0.jar
    100.0% [##########] 16.6 KiB (338.1 KiB / s)
  https://repo1.maven.org/maven2/org/scala-lang/scaladoc_3/3.0.0/scaladoc_3-3.0.0.jar
    100.0% [##########] 1.5 MiB (3.1 MiB / s)
  [info] Fetched artifacts of

  scala> 

Thanks to @renghen for this tip.

ScalaCourses

If you want to learn how to work effectively with Scala for functional and object-oriented programming, ScalaCourses.com is your best option. The course material is suitable for Scala 2 and Scala 3. Visit ScalaCourses.com to learn how to become a proficient Scala programmer.