Announcing Dotty 0.20.0-RC1 – `with` starting indentation blocks, inline given specializations and more
Greetings! We are excited to announce the 20th release of Dotty. This release brings a bunch of improvements to the language, such as with
keyword starting an indentation block, normal parameters after given parameters, inline givens specialization and more.
This release serves as a technology preview that demonstrates new language features and the compiler supporting them.
Dotty is the project name for technologies that are being considered for inclusion in Scala 3. Scala has pioneered the fusion of object-oriented and functional programming in a typed setting. Scala 3 will be a big step towards realising the full potential of these ideas. Its main objectives are to
- become more opinionated by promoting programming idioms we found to work well,
- simplify where possible,
- eliminate inconsistencies and surprising behaviours,
- build on strong foundations to ensure the design hangs together well,
- consolidate language constructs to improve the language’s consistency, safety, ergonomics, and performance.
You can learn more about Dotty on our website.
What’s new in the 0.20.0-RC1 technology preview?
Syntax change for type parameters of extension methods
When writing extension methods with type parameters, the type parameters must come first, e.g.:
def [T](xs: List[T]) append (ys: List[T]): List[T] = ...
Previously, the same would have been written as:
def (xs: List[T]) append [T] (ys: List[T]): List[T] = ...
An argument for the old syntax is that it aligns the definition and call syntax. On the other hand, the new syntax maintains the general rule that parameter introductions always come before parameter uses. The decisive argument to switch is to be consistent with the new collective parameter syntax, where append
would be written like this:
given [T](xs: List[T])
def append (ys: List[T]): List[T] = ...
To avoid misalignment of type parameters between definition and call syntax, we considered disallowing explicit type parameters for extension methods altogether, and to require that the method is called as a normal method instead. But that would not work for anonymous givens as in the last example above.
Infer private[this]
We now infer the private[this]
modifier for variables if all the accesses to a variable are via this. Explicit private[this]
and protected[this]
in code are deprecated under the -strict
flag.
The main reasons for dropping private[this]
are:
- It is syntactically an irregular case. A pair of brackets usually encloses a type, but
this
is a value. - Its effect over
private
is purely local and can be easily inferred. - It leads to bike shedding: should I use
private
orprivate[this]
? One is shorter but the other might be more efficient.
protected[this]
by now influences compiler decisions in no way at all. Hence it is reasonable to drop it.
with
keyword's new role
with
keyword can now optionally precede the class body. So that you can write your classes as follows:
trait A with {
def f: Int
}
class C(x: Int) extends A with {
def f = x
}
type T = A with {
def f: Int
}
Or, equivalently:
trait A with
def f: Int
class C(x: Int) extends A with
def f = x
type T = A with
def f: Int
The problem this change solves is that it is very easy to accidentally outdent a class member – and it will end up outside the class. The benefit of the new with
is that starts an indentation block. Since the compiler knows for sure an indentation block must follow, it will emit an error if you forget to indent your statement.
Inline given
specialization
It is now possible to specialize inline given
s with the help of <:
as follows:
trait A
class B extends A
inline given tc <: A = B()
val x: B = summon[A]
This change brings given
s even with the ordinary inline def
s.
Normal parameters can follow given
parameters
Previously normal parameters after given
parameter was disallowed mainly because they looked awkward with the old syntax. With the syntax being improved, this restriction is now lifted and you can write, e.g., the following program:
class C(val x: Int)
def f(x: Int)(given c: C)(y: Int) = x + c.x + y
then
is optional at line end
So the following is now legal:
val y1 =
if x > 0
1
else
2
It is easy to forget to put then
at the end of the line if nothing else follows it, but also easy to infer that it must be inserted there.
Metaprogramming Progress
We are making a steady progress developing and improving the metaprogramming features of Dotty. Here are metaprogramming highlights of this release:
Let us know what you think!
If you have questions or any sort of feedback, feel free to send us a message on our Gitter channel. If you encounter a bug, please open an issue on GitHub.
Contributing
Thank you to all the contributors who made this release possible!
According to git shortlog -sn --no-merges 0.19.0-RC1..0.20.0-RC1
these are:
99 Martin Odersky
64 Nicolas Stucki
16 Nikita Eshkeev
15 Guillaume Martres
9 Robert Stoll
8 Anatolii
5 Liu Fengyun
5 Olivier Blanvillain
3 Miles Sabin
2 Aggelos Biboudis
2 Jamie Thompson
2 Antoine Brunner
2 Ben Elliott
2 Guillaume R
1 noti0na1
1 Ashwin Bhaskar
1 Batanick
1 Bojan Dunaj
1 Harpreet Singh
1 Lucas
1 Lucas Jenß
1 Martijn Hoekstra
1 bishabosha
1 brunnerant
If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! Head to our Getting Started page for new contributors, and have a look at some of the good first issues. They make perfect entry points into hacking on the compiler.
We are looking forward to having you join the team of contributors.