Published 2019-09-07.
Last modified 2024-08-12.
Time to read: 3 minutes.
Scala 3 is a complete rewrite of the Scala compiler, using a new theoretical foundation. The Scala 3 microsite is here, and the GitHub project is here. The blog, with links to resources, is here.
This lecture is only meant as a quick preview and will not discuss details.
The Killer Feature
Dotty solves Scala’s binary compatibility problem, so there is no need for 3rd party libraries to be published specially for each version of Scala 3.
Compatibility
-
Scala 3 code can use many Scala 2 libraries because the Scala 3 compiler understands the classfile format for sources compiled with Scala 2.12+.
The exception is that Dotty does not support Scala 2 macros, so libraries such as
quill
won’t work until they are ported to Dotty. The following samplebuild.sbt
shows the magic incantation necessary to make this work.awslib_scala
is one of my libraries, and it is cross-published for Scala 2.10, 2.11, 2.12 and 2.13, but not Dotty. Nonetheless the library can be used in a Dotty project:val dottyVersion = "0.18.1-RC1" val scala212Version = "2.12.9"
lazy val root = project .in(file(".")) .settings( name := "dotty-cross", version := "0.1.0",
libraryDependencies ++= Seq( "com.micronautics" %% "awslib_scala" % "1.1.13" withSources(), "com.novocode" % "junit-interface" % "0.11" % Test ).map(_.withDottyCompat(scalaVersion.value)),
resolvers += "micronautics/scala on bintray" at "https://dl.bintray.com/micronautics/scala",
// To make the default compiler and REPL use Dotty scalaVersion := dottyVersion,
// To cross compile with Dotty and Scala 2 crossScalaVersions := Seq(dottyVersion, "2.13.0", scala212Version) ) -
Scala 2 implicits are being replaced by
given
s; this is dedicated syntax to support typeclasses. Scala 2’s typeclasses must be home-made, while Dotty provides proper support. -
The
implicitly
method fromPredef
(discussed in the Implicit Conversions and Predef lectures of the Intermediate Scala course). - Value classes (discussed in the Implicit Values lecture of the Intermediate Scala course) are being replaced by opaque types.
- Scala 3 and Scala 2 share the same standard library, which means they both use the same collection classes.
- With some small tweaks it is possible to cross-build code for both Scala 2 and 3. A guide will be published that defines the shared language subset that can be compiled under both versions.
- The Scala 3 compiler has a
-language:
Scal
option that lets it compile most Scala 2 code and at the same time highlights necessary rewritings as migration warnings.a
2 - The compiler can perform many of the rewritings automatically using a
-rewrite
option. - Migration through automatic rewriting will also be offered through the
scalafix
tool, which can convert sources to the cross-buildable language subset without requiring Scala 3 to be installed.
Major New Features
The high-level new features are:
Intersection types
Intersection types are similar to Scala 2 trait mixins (which we will discuss in the Scala Traits lecture). This is useful for ad-hoc polymorphism, used in typeclasses.
def foo(arg: Serializable & Comparable): Unit
Union Types
Union types
are similar to C language struct
s and form the basis for proper enumerations
(Scala 2’s support for enumerations is weak).
Repeated by-name parameters
We will discuss varargs and placeholder splat in the
Classes Part 2 lecture,
Function
s in the Functions are First Class lecture,
by name parameters in the
Higher-Order Functions lecture of the
Intermediate Scala course.
In this code, => T*
means Function0[Seq[T]]
.
object DaysOfTheWeek{ def foo(a: => Any*) = () def bar(a: => Any*) = foo(a : _*) def baz(a: => Seq[Any]) = foo(a : _*)
bar(???, ???) baz(Seq(???, ???)) }
Trait parameters
Traits will be discussed in the Scala Traits lecture. Dotty changes traits so they are more like abstract classes, discussed in the Classes Part 2 lecture. I’ve wanted this feature many times over the years.
Improved lazy val initialization
Lazy vals work like magic, except when they don’t. Dotty lazy values:
- Do not deadlock
- Allow concurrent initialization of independent fields
- Are thread unsafe by default
- Are 40% faster to access by default
- Need
@volatile
to request thread safety - If
@volatile
is used, 5% faster than Scala 2 (one non-volatile read vs volatile read)
The following code presents a problem for Scala 2.
object A { lazy val a0 = B.b // <-- Thread 1, grabs lock lazy val a1 = 17 // Potential deadlock }
object B { lazy val b = A.a1 // <-- Thread 2, grabs lock }
Scala 3 solves the problem like this:
object C { lazy val a0 = { /* long computation with IO */ } // <-- Thread 1 lazy val a1 = 42 // <-- Thread 2 will be waiting for Thread 1 to finish }
Detailed Features
Scala 3’s features are prominently displayed on the microsite; here they are:
- Intersection Types
- Union Types
- Type lambdas
- Context query
- Trait parameters
- Implied Instances
- Inferable parameters
- Extension Methods
- Opaque Type Aliases
- Toplevel definitions
- Export clauses
- Vararg patterns
- Creator applications
- @static methods and fields
- Learn Scala
- Option-less pattern matching
- Multiversal equality
- Erased Terms
- Auto-Specialization
- Whole program optimizer
- HList & HMaps/Record types
- Metaprogramming (macros)
See the Scala 3 Reference for a comprehensive list.
Create a Dotty project
SBT works with Dotty just as it does with Scala 2.x.
To create a new Dotty project, use the giter8
template called
scala/scala3.g8
, type:
$ sbt new scala/scala3.g8
... lots of output ...
A template to demonstrate a minimal Dotty application
name [Dotty Project Template]:
Template applied in /mnt/c/work/experiments/dotty/./dotty-project-template
To create a new Scala 3 project that cross-compiles with Scala 2 use the
scala3-cross.g8
giter8
template.
$ sbt new scala/scala3-cross.g8
... lots of output...
A template to demonstrate a minimal Dotty/Scala 2 cross-compiled project
name [Dotty Cross]:
Template applied in /mnt/c/work/experiments/dotty/./dotty-cross
See the Scala 3 Example Project.
© Copyright 1994-2024 Michael Slinn. All rights reserved.
If you would like to request to use this copyright-protected work in any manner,
please send an email.
This website was made using Jekyll and Mike Slinn’s Jekyll Plugins.