<img height="1" width="1" src="https://www.facebook.com/tr?id=1076094119157733&amp;ev=PageView &amp;noscript=1">

What is coming with Dotty?

Posted by Ferhat Aydin on Mon, Jul 3, 2017

At the Scaladays Copenhagen Opening Keynote, Martin Odersky explains why Dotty has been needed, what is different in Dotty and what kind of problems will be solved when it becomes stable. The other important talk is Dimitry Petrashko's Dotty is coming, especially the Q&A session gives very valuable explanations to some of new dotty features.

The core dotty team is working hard to create a more powerful and stable, simpler, and more reasonable compiler (dotc) for Scala. Not only a new compiler, but also many new features have been added, many current features have already been dropped or changed. The dotty team cares about community engagement seriously and awaits feedback while many things are in progress or even at the decision stage. In order to feed the community about what's going on, dotty provides a very clean docs page in which all the details of these features and changes are explained. Even if dotty is very premature now, you can create a new empty sbt project based on dotty by using dotty.g8 template. There is also a dotty-example-project repo which contains almost all new dotty features with compiling and running code examples.

After watching Odersky's talk, I checked the dotty docs and example repos. I noticed that the dotty-example-project repo contains only a simple Union Types example. I started to try existing examples from the docs to see how they are working and how much I can feel comfortable with new features. Then, I tried more things by extending current examples and adding new ones. All of these examples are now in the dotty-example-project repo, after my two pull-requests (1 and 2) are merged.

In this post, I would like to go over each dotty feature with examples by using the above mentioned resources. I will get help from Odersky's talk a lot and you can assume this post is a bit of a transcript of his talk;

What is Dotty?

Dotty is a new programming language (yes, it has been written with Scala and will be the Scala 3.0) with a new compiler dotc and all other tools. Dotty aims to simplify and strengthen the core of Scala in the light of Dot Calculus which provides a strong and consistent foundation and specification.

What's new?

After a short summary and references to dotty which means you can go deep inside if you want and are curious, we can start explain new features and changes with code examples.

Types

As Odersky explains in his talk, type systems of current Scala are very complicated, unsatisfactory and have serious problems such as complex type checking logic and type inference rules. Dotty aims to provide a stronger type system which is more simple, soundness, and consistent than the type system of Scala.

Here is the new features and changes about types in dotty;

  • "Existential types (T forSome { type A }) and type projections (T#A) are removed from the language because both are unsound and cause problems because of their inconsistent interaction within the type system.", says Odersky.

  • Compound types (T with U) are replaced with Union Types (T | U) and Intersection Types (T & U) which are based on a strong subtyping lattice, where T & U is the lower bound and T | U is the upper bound if T is subtype of U (T <: U).

  • Union types represents sum types. Here is a simple example which we define an algebra for division operation:
  • Intersection Types represents product types. A simple example which shows how you can define a Point with the intersection of two types (X and Y) and calculate the euclidean distance between them by using intersection types:
  • Type Lambda is a new feature. In the current version of Scala, there is no intentional type lambda support provided by compiler and the community has found that it is possible by using structural types and type projection. However, creating a type lambda in Scala is painful in terms of syntax, but kind-projector compiler plugin helps to make a bit cleaner. You can check this blog post if you want to read more about type lambdas. Instead of type projections which are removed from the language in dotty as said above, built-in type lambda support is here. There are two different ways for defining your type lambdas as you can see in the example below;
  • Named Type Arguments is a new feature of dotty which provides type arguments of methods that can be named as well as by position like named value arguments (def three(a: Int = 3): String = "three"). An example of it can be given by using Functors which needs multi type parameters:

Traits

  • Trait Parameters: In dotty, traits can take parameters. In contrast to abstract vals in the current Scala traits where parameters are initialized after or during the constructor of the concrete type, trait parameters in dotty are evaluated immediately so you can even use them in the constructor of the concrete type if you need.

With this new feature there is no need anymore for early definitions like;

Instead, you can pass parameters to the trait directly as in this example;

One important problem related to trait parameters would be the Inheritance Diamonds again from Odersky's talk;

Two rules provide the solution to that problem; - traits can never pass parameters to other traits, only classes can. - the first class that is implementing trait T (in the inheritance hierarchy) must parameterized it. Not second or third ones.

Enums

Finally, enum support with a new shiny enum keyword has arrived in dotty and constructing enums in Scala will not be a pain anymore (in the future). A classical enum java example can be shown as follows;

Also, with enum feature, ADTs (Algebraic Data Types) and GADTs (Generalized ADT) are supported without any extra cost. You can check the docs to learn more about. A short example to see how you can construct your own ADT with enums is as follows;

Implicits

Implicits are very powerful and useful in terms of program syntesis, but they are also complex and puzzler. Also, they may cause too much repetition in the code by passing implicit parameters during the flow of the code.

  • Implicit conversion One puzzler is wrong implicits in the scope which may cause wrong results. To be able to prevent such errors, in dotty, implicit conversion rules are tightened. Any value of type Function1 or its subtypes can be used in implicit conversion at the current Scala. You can check this scala puzzler. In dotty, you need to implement the new abstract class ImplicitConverter[-T, +U] extends Function1[T, U] class for your intented conversion explicitly. And, dotty only considers methods as implicit conversions, implicit vals should not be allowed for conversion.
  • Implicit Functions: Since, implicit parameters represent context in general, they cause lots of repetition. Dotty solves that problem by introducing implicit function types.

Now you can pass implicit parameters as implicit functions. For example, you need ExecutionContext when working with scala.concurrent.Future and they are passed as implicit parameters in general. You can now define as implicit functions as this example for your ExecutionContext;

As a bonus, in dotty, implicit parameters can be passed as by-name. This way, implicit parameters will be evaluated if only the code flow will reach to the point where implicit parameters are needed. In the following example, the implicit parser is not evaluated if the string is empty.

Pattern Matching

"Dotty implementation of pattern matching was greatly simplified compared to scalac. From a user perspective, this means that Dotty generated patterns are a lot easier to debug, as variables all show up in debug modes and positions are correctly preserved" from the docs.

Moreover, you don't need to define your extractors only in Option-based way, dotty supports 4 different extractor patterns. You can check this example for a complete use cases of these patterns in detail.

Multiversal Equality

Current scala == and != operators are based on Java equals method. It allows you to compare different types without any compiler error or warning. In dotty, universal equality is getting more typesafe with multiversal equality. You need to define an implicit Eq for your intented types to be compared. It only provides compiler level safety, runtime is again based on Java's equals.

You may want to check Dotty Predef, implicit Eq instances are already on there for primitive types. EqAny is on the predef for just backward compatibility and if you exclude it, you will need explicit Eq instances for your types to compare as shown;

Lazy Vals

Lazy vals are not thread safe in dotty. If you need thread safety, you need to mark your lazy vals with @volatile annotation.

Auto Parameter Tupling of Function Parameters

At last, you do not need pattern-matching decomposition for your function combinators.

Conclusion

That's all for now, we went over almost all of the new features and changes that are coming with dotty. When new features arrive, we will cover them in a new post.

Topics: Scala, lambdas, Dotty, Enums

Posts by Topic

see all

Subscribe to Email Updates