|
| 1 | +--- |
| 2 | +layout: blog-page |
| 3 | +title: Announcing Dotty 0.15.0-RC1 – the fully bootstrapped compiler |
| 4 | +author: Anatolii Kmetiuk |
| 5 | +authorImg: /images/anatolii.png |
| 6 | +date: 2019-05-24 |
| 7 | +--- |
| 8 | + |
| 9 | +Hi! We are very excited to announce the 15th release of Dotty. The most exciting thing in this release is the full bootstrap for Dotty introduced by PR [#5923](https://github.com/lampepfl/dotty/pull/5923)🎉😍. This means that we now always compile Dotty with Dotty itself, hence we can use use all the new features in the compiler code base. |
| 10 | + |
| 11 | +With this release comes a bunch of new features and improvements, such as the ability to enforce whether an operator is intended to be used in an infix position, the type safe pattern bindings and more. |
| 12 | + |
| 13 | +This release serves as a technology preview that demonstrates new |
| 14 | +language features and the compiler supporting them. |
| 15 | + |
| 16 | +Dotty is the project name for technologies that are being considered for |
| 17 | +inclusion in Scala 3. Scala has pioneered the fusion of object-oriented and |
| 18 | +functional programming in a typed setting. Scala 3 will be a big step towards |
| 19 | +realising the full potential of these ideas. Its main objectives are to |
| 20 | + |
| 21 | +- become more opinionated by promoting programming idioms we found to work well, |
| 22 | +- simplify where possible, |
| 23 | +- eliminate inconsistencies and surprising behaviours, |
| 24 | +- build on strong foundations to ensure the design hangs together well, |
| 25 | +- consolidate language constructs to improve the language’s consistency, safety, ergonomics, and |
| 26 | + performance. |
| 27 | + |
| 28 | +You can learn more about Dotty on our [website](https://dotty.epfl.ch). |
| 29 | + |
| 30 | +<!--more--> |
| 31 | + |
| 32 | +This is our 15th scheduled release according to our |
| 33 | +[6-week release schedule](https://dotty.epfl.ch/docs/contributing/release.html). |
| 34 | + |
| 35 | +# What’s new in the 0.15.0-RC1 technology preview? |
| 36 | +## Full Bootstrap |
| 37 | +Bootstrapping Dotty is a big milestone for us and in compiler construction in general. Firstly, we feel more confident that our compiler works as is (even without reusing the new features). Secondly, in the immediate future, we will be able to reuse many of the features that dotty proposes within dotty itself. For example, we have no fewer than 2641 occurrences of the text string (implicit ctx: Context) in the compiler that we can scrap with [Contextual Function types](https://www.scala-lang.org/blog/2016/12/07/implicit-function-types.html). Big milestones have high risk/high gain and we must be attentive. That is the reason that we will wait a bit until we start using new features. Consequently, at the moment we cross-compile the build with 2.12 on the CI so that we don't accidentally start using Dotty features in case we need to revise the bootstrap process (we'll start using Dotty features eventually, but let's wait until we're confident that this setup works well enough). |
| 38 | + |
| 39 | +Check the following for more information [#5923 (comment)](https://github.com/lampepfl/dotty/pull/5923#issuecomment-485421148) and please let us know if you have any incremental compilation issues or anything else! |
| 40 | + |
| 41 | +## Operator Rules |
| 42 | +This change addresses the problem of the regulation of whether an operator is supposed to be used in an infix position. The motivation is for the library authors to be able to enforce whether a method or a type is supposed to be used in an infix position by the users. This ability will help to make code bases more consistent in the way the calls to methods are performed. |
| 43 | + |
| 44 | +Methods with symbolic names like `+` are allowed to be used in an infix position by default: |
| 45 | + |
| 46 | +```scala |
| 47 | +scala> case class Foo(x: Int) { def +(other: Foo) = x + other.x } |
| 48 | +// defined case class Foo |
| 49 | + |
| 50 | +scala> Foo(1) + Foo(2) |
| 51 | +val res0: Int = 3 |
| 52 | +``` |
| 53 | + |
| 54 | +Methods with alphanumeric names are not allowed to be used in an infix position. Breaking this constraint will raise a deprecation warning: |
| 55 | + |
| 56 | +```scala |
| 57 | +scala> case class Foo(x: Int) { def plus(other: Foo) = x + other.x } |
| 58 | +// defined case class Foo |
| 59 | + |
| 60 | +scala> Foo(1) plus Foo(2) |
| 61 | +1 |Foo(1) plus Foo(2) |
| 62 | + | ^^^^ |
| 63 | + |Alphanumeric method plus is not declared @infix; it should not be used as infix operator. |
| 64 | + |The operation can be rewritten automatically to `plus` under -deprecation -rewrite. |
| 65 | + |Or rewrite to method syntax .plus(...) manually. |
| 66 | +val res1: Int = 3 |
| 67 | + |
| 68 | +scala> Foo(1).plus(Foo(2)) |
| 69 | +val res2: Int = 3 |
| 70 | +``` |
| 71 | + |
| 72 | +As the warning says, if you want the users of the method to be able to use it in an infix position, you can do so as follows: |
| 73 | + |
| 74 | +```scala |
| 75 | +scala> import scala.annotation.infix |
| 76 | + |
| 77 | +scala> case class Foo(x: Int) { @infix def plus(other: Foo) = x + other.x } |
| 78 | +// defined case class Foo |
| 79 | + |
| 80 | +scala> Foo(1) plus Foo(2) |
| 81 | +val res3: Int = 3 |
| 82 | +``` |
| 83 | + |
| 84 | +To smoothen the migration, the deprecation warnings will only be emitted if you compile with the `-strict` flag under Scala 3. Alphanumeric methods that are defined without the `@infix` annotation used in an infix position will be deprecated by default starting with Scala 3.1. |
| 85 | + |
| 86 | +For more information, see the the [documentation](http://dotty.epfl.ch/docs/reference/changed-features/operators.html#the-infix-annotation). Note that the `@alpha` annotation also described in the documentation is planned for the future and is not available in this release. |
| 87 | + |
| 88 | +## `given` clause comes last |
| 89 | +In the previous release, you could write something like this: |
| 90 | + |
| 91 | +```scala |
| 92 | +implied for String = "foo" |
| 93 | +def f(x: Int) given (y: String) (z: Int) = x + z |
| 94 | +f(1)(3) |
| 95 | +``` |
| 96 | + |
| 97 | +Now, however, `given` clauses must come last. The above code will fail with: |
| 98 | + |
| 99 | +``` |
| 100 | +-- Error: ../issues/Playground.scala:3:34 -------------------------------------- |
| 101 | +3 | def f(x: Int) given (y: String) (z: Int) = x + z |
| 102 | + | ^ |
| 103 | + | normal parameters cannot come after `given' clauses |
| 104 | +one error found |
| 105 | +``` |
| 106 | + |
| 107 | +The following snippet is the correct way to express the program in question: |
| 108 | + |
| 109 | +```scala |
| 110 | +implied for String = "foo" |
| 111 | +def f(x: Int)(z: Int) given (y: String) = x + z |
| 112 | +f(1)(3) |
| 113 | +``` |
| 114 | + |
| 115 | +We changed this to reduce confusion when calling functions with mixed explicit and implied parameters. |
| 116 | + |
| 117 | +## Type-safe Pattern Bindings |
| 118 | +```scala |
| 119 | + val xs: List[Any] = List(1, 2, 3) |
| 120 | + val (x: String) :: _ = xs // error: pattern's type String is more specialized |
| 121 | + // than the right hand side expression's type Any |
| 122 | +``` |
| 123 | + |
| 124 | +The above code will fail with a compile-time error in Scala 3.1 and in Scala 3 with the `-strict` flag. In contrast, in Scala 2, the above would have compiled fine but failed on runtime with an exception. |
| 125 | + |
| 126 | +Dotty compiler will allow such a pattern binding only if the pattern is *irrefutable* – that is, if the right-hand side conforms to the pattern's type. E.g. the following is OK: |
| 127 | + |
| 128 | +```scala |
| 129 | + val pair = (1, true) |
| 130 | + val (x, y) = pair |
| 131 | +``` |
| 132 | + |
| 133 | +If we want to force the pattern binding if the pattern is not irrefutable, we can do so with an annotation: |
| 134 | + |
| 135 | +```scala |
| 136 | + val xs: List[Any] = List("1", "2", "3") |
| 137 | + val (x: String) :: _: @unchecked = xs |
| 138 | +``` |
| 139 | + |
| 140 | +The same is implemented for pattern bindings in `for` expressions: |
| 141 | + |
| 142 | +```scala |
| 143 | + val elems: List[Any] = List((1, 2), "hello", (3, 4)) |
| 144 | + for ((x, y) <- elems) yield (y, x) // error: pattern's type (Any, Any) is more specialized |
| 145 | + // than the right hand side expression's type Any |
| 146 | +``` |
| 147 | + |
| 148 | +For the migration purposes, the above change will only take effect in Scala 3.1. You can use it in Scala 3 with the `-strict` flag. |
| 149 | + |
| 150 | +For more information, see the [documentation](http://dotty.epfl.ch/docs/reference/changed-features/pattern-bindings.html). |
| 151 | + |
| 152 | +## Further improvements to Generalised Algebraic Data Types (GADTs) support |
| 153 | +In this release, we've further improved our support for GADTs. Most notably, we now support variant GADTs, thus fixing [#2985](https://github.com/lampepfl/dotty/issues/2985): |
| 154 | + |
| 155 | +```scala |
| 156 | +enum Expr[+T] { |
| 157 | + case StrLit(s: String) extends Expr[String] |
| 158 | + case Pair[A, B](a: Expr[A], b: Expr[B]) extends Expr[(A, B)] |
| 159 | +} |
| 160 | + |
| 161 | +def eval[T](e: Expr[T]): T = e match { |
| 162 | + case Expr.StrLit(s) => s |
| 163 | + case Expr.Pair(a, b) => (eval(a), eval(b)) |
| 164 | +} |
| 165 | +``` |
| 166 | + |
| 167 | +We've also plugged a few soundness problems (e.g. [#5667](https://github.com/lampepfl/dotty/issues/5667)) caused by inferring too much when matching on abstract, union and intersection types. For more information, see PR [#5736](https://github.com/lampepfl/dotty/pull/5736). |
| 168 | + |
| 169 | +## Other changes |
| 170 | +Some of the other notable changes include the following: |
| 171 | + |
| 172 | +- Singletons are now allowed in union types. E.g. the following is allowed: `object foo; type X = Int | foo.type`. |
| 173 | +- A bunch of improvements was made for the type inference system – see, e.g., PRs [#6454](https://github.com/lampepfl/dotty/pull/6454) and [#6467](https://github.com/lampepfl/dotty/pull/6467). |
| 174 | +- Improvements to the Scala 2 code support which, in particular, improves Cats support – see PRs [#6494](https://github.com/lampepfl/dotty/pull/6494) and [#6498](https://github.com/lampepfl/dotty/pull/6498). |
| 175 | + |
| 176 | +# Let us know what you think! |
| 177 | + |
| 178 | +If you have questions or any sort of feedback, feel free to send us a message on our |
| 179 | +[Gitter channel](https://gitter.im/lampepfl/dotty). If you encounter a bug, please |
| 180 | +[open an issue on GitHub](https://github.com/lampepfl/dotty/issues/new). |
| 181 | + |
| 182 | +## Contributing |
| 183 | + |
| 184 | +Thank you to all the contributors who made this release possible! |
| 185 | + |
| 186 | +According to `git shortlog -sn --no-merges 0.14.0-RC1..0.15.0-RC1` these are: |
| 187 | + |
| 188 | +``` |
| 189 | +TODO |
| 190 | +``` |
| 191 | + |
| 192 | +If you want to get your hands dirty and contribute to Dotty, now is a good time to get involved! |
| 193 | +Head to our [Getting Started page for new contributors](https://dotty.epfl.ch/docs/contributing/getting-started.html), |
| 194 | +and have a look at some of the [good first issues](https://github.com/lampepfl/dotty/issues?q=is%3Aissue+is%3Aopen+label%3Aexp%3Anovice). |
| 195 | +They make perfect entry points into hacking on the compiler. |
| 196 | + |
| 197 | +We are looking forward to having you join the team of contributors. |
| 198 | + |
| 199 | +## Library authors: Join our community build |
| 200 | + |
| 201 | +Dotty now has a set of widely-used community libraries that are built against every nightly Dotty |
| 202 | +snapshot. Currently this includes ScalaPB, algebra, scalatest, scopt and squants. |
| 203 | +Join our [community build](https://github.com/lampepfl/dotty-community-build) |
| 204 | +to make sure that our regression suite includes your library. |
| 205 | + |
| 206 | +[Scastie]: https://scastie.scala-lang.org/?target=dotty |
| 207 | + |
| 208 | +[@odersky]: https://github.com/odersky |
| 209 | +[@DarkDimius]: https://github.com/DarkDimius |
| 210 | +[@smarter]: https://github.com/smarter |
| 211 | +[@felixmulder]: https://github.com/felixmulder |
| 212 | +[@nicolasstucki]: https://github.com/nicolasstucki |
| 213 | +[@liufengyun]: https://github.com/liufengyun |
| 214 | +[@OlivierBlanvillain]: https://github.com/OlivierBlanvillain |
| 215 | +[@biboudis]: https://github.com/biboudis |
| 216 | +[@allanrenucci]: https://github.com/allanrenucci |
| 217 | +[@Blaisorblade]: https://github.com/Blaisorblade |
| 218 | +[@Duhemm]: https://github.com/Duhemm |
| 219 | +[@AleksanderBG]: https://github.com/AleksanderBG |
| 220 | +[@milessabin]: https://github.com/milessabin |
| 221 | +[@anatoliykmetyuk]: https://github.com/anatoliykmetyuk |
0 commit comments