Skip to content

Commit 2086360

Browse files
committed
Dotty 0.2.0-RC1 release announcement draft.
1 parent b989884 commit 2086360

File tree

1 file changed

+360
-0
lines changed

1 file changed

+360
-0
lines changed
Lines changed: 360 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
---
2+
layout: blog-page
3+
title: Announcing Dotty 0.2.0-RC1, with new optimizations, improved stability and IDE support
4+
author: Dmytro Petrashko
5+
authorImg: /images/petrashko.jpg
6+
date: 2017-05-31
7+
---
8+
9+
Today, we are excited to release Dotty version 0.2.0-RC1. This release
10+
serves as a technology preview that demonstrates new language features
11+
and the compiler supporting them.
12+
13+
This release is based on [previous milestone](/blog/2017/05/31/first-dotty-milestone-release.html).
14+
The highlights of this release are:
15+
- substantial improvement of quality of generated code for pattern matching
16+
- improvements in VS Code IDE stability
17+
- improved compatibility with scalac
18+
- initial support for reproducible builds
19+
20+
21+
<!--more-->
22+
23+
This is our second scheduled release according to our [6-week release schedule](http://dotty.epfl.ch/docs/usage/version-numbers.html).
24+
25+
# What’s in the 0.2.0-RC1 technology preview?
26+
The [previous technology preview](/blog/2017/05/31/first-dotty-milestone-release.html) has shipped new language planned for Scala 3:
27+
[Intersection Types](http://dotty.epfl.ch/docs/reference/intersection-types.html),
28+
[Union Types](http://dotty.epfl.ch/docs/reference/union-types.html),
29+
[Trait Parameters](http://dotty.epfl.ch/docs/reference/trait-parameters.html),
30+
[Enumerations](http://dotty.epfl.ch/docs/reference/enums/enums.html),
31+
[Algebraic Data Types](http://dotty.epfl.ch/docs/reference/enums/adts.html),
32+
[By-Name Implicits](http://dotty.epfl.ch/docs/reference/implicit-by-name-parameters.html).
33+
34+
This technology preview is geared towards improving stability and reliability. It includes:
35+
36+
- [Local optimizations upstreamed from Dotty Linker](https://github.com/lampepfl/dotty/pull/2513), [2647](https://github.com/lampepfl/dotty/pull/2647) by ([@OlivierBlanvillain](https://github.com/OlivierBlanvillain). See more details below.
37+
- [Optimizing Pattern Matcher](https://github.com/lampepfl/dotty/pull/2829) by ([@odersky](https://github.com/odersky)
38+
- [Idempotency checks](https://github.com/lampepfl/dotty/pull/2756) are the first step to reproducible builds
39+
- [Faster Base class sets](https://github.com/lampepfl/dotty/pull/2676) by ([@odersky](https://github.com/odersky) and ([@darkdimius](https://twitter.com/darkdimius)
40+
- Huge number of fixes to IDE and Dotty Language Server covering:
41+
42+
- [Fix hover-on-type for implicitly converted expressions](https://github.com/lampepfl/dotty/pull/2836)
43+
- [Fixes to find all references in external projects](https://github.com/lampepfl/dotty/pull/2810), [2773](https://github.com/lampepfl/dotty/pull/2773/files)
44+
- [Fix conflict with dragos-vscode-scala](https://github.com/lampepfl/dotty/pull/2777)
45+
- [Fix ide crash on non-parsable file](https://github.com/lampepfl/dotty/pull/2752)
46+
- [Fix hover functionality for enum classes](https://github.com/lampepfl/dotty/pull/2722)
47+
- [Report errors on Dotty Language Server initialization](https://github.com/lampepfl/dotty/pull/2708)
48+
- [Fixes to sbt setting up Dotty IDE](https://github.com/lampepfl/dotty/pull/2690)
49+
- General stability improvements [2838](https://github.com/lampepfl/dotty/pull/2838), [2787](https://github.com/lampepfl/dotty/pull/2787), [2692](https://github.com/lampepfl/dotty/pull/2692)
50+
51+
- Scalac compatibility improvements:
52+
53+
- [Support Scala 2.12 traits](https://github.com/lampepfl/dotty/pull/2685)
54+
- [Fixes to handling of Scala 2 classfiles](https://github.com/lampepfl/dotty/pull/2834/files)
55+
- [Scalac parser crashes on Dotty.jar](https://github.com/lampepfl/dotty/pull/2719)
56+
57+
- Java compatibility improvements:
58+
59+
- [Fixes to handing of Java generic signatures](https://github.com/lampepfl/dotty/pull/2831)
60+
- [java.lang.System.out is final but that's a lie](https://github.com/lampepfl/dotty/pull/2781)
61+
62+
- Improved error messages:
63+
64+
- [Nicer error message for "implicit function type needs non-empty parameter list"](https://github.com/lampepfl/dotty/pull/2821)
65+
- [Nicer error message for nonsensical modifier combination](https://github.com/lampepfl/dotty/pull/2807/files), [2747](https://github.com/lampepfl/dotty/pull/2747)
66+
- [Nicer error message for supercall inside @inline method](https://github.com/lampepfl/dotty/pull/2740)
67+
- [Check that case classes don't inherit case classes](https://github.com/lampepfl/dotty/pull/2790)
68+
- [Check that named parameters don't conflict with positional ones](https://github.com/lampepfl/dotty/pull/2785)
69+
70+
- Improved command line handling:
71+
72+
- [Support params in a file like @file.txt](https://github.com/lampepfl/dotty/pull/2765)
73+
74+
- Type system stability:
75+
76+
- [Handle wildcard types in unions and intersections](https://github.com/lampepfl/dotty/pull/2742)
77+
78+
- Fixes to implicit search:
79+
80+
- [Fix shadowing of higher order implicits](https://github.com/lampepfl/dotty/pull/2739)
81+
82+
83+
## Better generated code:
84+
85+
As was [spotted](https://twitter.com/gkossakowski/status/870243464528744449) by [@gkossakowski](https://twitter.com/gkossakowski)
86+
In the previous release Dotty was on par with Scala 2.11 in speed. But why is that?
87+
The reason is that Dotty compiled by dotty had really horrible code generated or pattern matching.
88+
89+
Let's illustrate on a simple example:
90+
91+
```
92+
case class CC(a: Int, b: Object)
93+
94+
def foo(x: Any): Int = {
95+
val (a, b) = x match {
96+
case CC(s @ 1, CC(t, _)) =>
97+
(s , 2)
98+
case _ => (42, 43)
99+
}
100+
a + b
101+
}
102+
103+
def booleans(a: Object) = {
104+
val (b1, b2) = (a.isInstanceOf[CC], a.isInstanceOf[List[Int]])
105+
(b1, b2) match {
106+
case (true, true) => true
107+
case (false, false) => true
108+
case _ => false
109+
}
110+
}
111+
```
112+
113+
114+
Dotty that was released in the previous milestone didn't contain any optimizations and generated horrible code for it.
115+
The java-with-goto code below is equivalent to what dotty hs generated.
116+
117+
```
118+
// output of dotc 0.1.2-RC1
119+
public int foo(Object x) {
120+
var3_2 = x;
121+
if (!(var3_2 instanceof CC)) ** GOTO lbl-1000
122+
var4_3 = (CC)var3_2;
123+
if (CC$.MODULE$.unapply((CC)var3_2) == null) ** GOTO lbl-1000
124+
var5_4 = CC$.MODULE$.unapply((CC)var3_2);
125+
s = var5_4._1();
126+
var7_6 = var5_4._2();
127+
if (1 != s) ** GOTO lbl-1000
128+
var8_7 = s;
129+
if (!(var7_6 instanceof CC)) ** GOTO lbl-1000
130+
var9_8 = (CC)var7_6;
131+
if (CC$.MODULE$.unapply((CC)var7_6) != null) {
132+
var10_9 = CC$.MODULE$.unapply((CC)var7_6);
133+
var11_10 = var10_9._2();
134+
v0 = Tuple2..MODULE$.apply((Object)BoxesRunTime.boxToInteger((int)1), (Object)BoxesRunTime.boxToInteger((int)2));
135+
} else lbl-1000: // 5 sources:
136+
{
137+
v0 = Tuple2..MODULE$.apply((Object)BoxesRunTime.boxToInteger((int)42), (Object)BoxesRunTime.boxToInteger((int)43));
138+
}
139+
var2_11 = v0;
140+
a = BoxesRunTime.unboxToInt((Object)var2_11._1());
141+
b = BoxesRunTime.unboxToInt((Object)var2_11._2());
142+
return a + b;
143+
}
144+
145+
public boolean booleans(Object a) {
146+
Tuple2 tuple2 = Tuple2..MODULE$.apply((Object)BoxesRunTime.boxToBoolean((boolean)(a instanceof CC)), (Object)BoxesRunTime.boxToBoolean((boolean)(a instanceof List)));
147+
boolean b1 = BoxesRunTime.unboxToBoolean((Object)tuple2._1());
148+
boolean b2 = BoxesRunTime.unboxToBoolean((Object)tuple2._2());
149+
Tuple2 tuple22 = Tuple2..MODULE$.apply((Object)BoxesRunTime.boxToBoolean((boolean)b1), (Object)BoxesRunTime.boxToBoolean((boolean)b2));
150+
Option option = Tuple2..MODULE$.unapply(tuple22);
151+
if (!option.isEmpty()) {
152+
Tuple2 tuple23 = (Tuple2)option.get();
153+
boolean bl = BoxesRunTime.unboxToBoolean((Object)tuple23._1());
154+
boolean bl2 = BoxesRunTime.unboxToBoolean((Object)tuple23._2());
155+
if (bl) {
156+
boolean bl3 = bl;
157+
if (bl2) {
158+
boolean bl4 = bl2;
159+
return true;
160+
}
161+
}
162+
}
163+
Option option2 = Tuple2..MODULE$.unapply(tuple22);
164+
if (option2.isEmpty()) return false;
165+
Tuple2 tuple24 = (Tuple2)option2.get();
166+
boolean bl = BoxesRunTime.unboxToBoolean((Object)tuple24._1());
167+
boolean bl5 = BoxesRunTime.unboxToBoolean((Object)tuple24._2());
168+
if (bl) return false;
169+
boolean bl6 = bl;
170+
if (bl5) return false;
171+
boolean bl7 = bl5;
172+
return true;
173+
}
174+
```
175+
176+
Due to new optimizing pattern matcher, dotty now is able to generate the code below without `-optimise`
177+
178+
```
179+
// output of 0.2.0-RC1 without -optimise
180+
public int foo(Object x) {
181+
var3_2 = x;
182+
if (!(var3_2 instanceof CC)) ** GOTO lbl-1000
183+
var4_3 = CC$.MODULE$.unapply((CC)var3_2);
184+
s = var5_4 = var4_3._1();
185+
if (1 == var5_4 && (var7_6 = var4_3._2()) instanceof CC) {
186+
t = CC$.MODULE$.unapply((CC)var7_6)._1();
187+
v0 = Tuple2..MODULE$.apply((Object)BoxesRunTime.boxToInteger((int)1), (Object)BoxesRunTime.boxToInteger((int)2));
188+
} else lbl-1000: // 2 sources:
189+
{
190+
v0 = Tuple2..MODULE$.apply((Object)BoxesRunTime.boxToInteger((int)42), (Object)BoxesRunTime.boxToInteger((int)43));
191+
}
192+
var2_8 = v0;
193+
a = BoxesRunTime.unboxToInt((Object)var2_8._1());
194+
b = BoxesRunTime.unboxToInt((Object)var2_8._2());
195+
return a + b;
196+
}
197+
198+
public boolean booleans(Object a) {
199+
Tuple2 tuple2 = Tuple2..MODULE$.apply((Object)BoxesRunTime.boxToBoolean((boolean)(a instanceof CC)), (Object)BoxesRunTime.boxToBoolean((boolean)(a instanceof List)));
200+
boolean b1 = BoxesRunTime.unboxToBoolean((Object)tuple2._1());
201+
boolean b2 = BoxesRunTime.unboxToBoolean((Object)tuple2._2());
202+
Tuple2 tuple22 = Tuple2..MODULE$.apply((Object)BoxesRunTime.boxToBoolean((boolean)b1), (Object)BoxesRunTime.boxToBoolean((boolean)b2));
203+
if (tuple22 != null) {
204+
boolean bl;
205+
boolean bl2 = BoxesRunTime.unboxToBoolean((Object)tuple22._1());
206+
if (!bl2) {
207+
bl = bl2;
208+
} else {
209+
if (BoxesRunTime.unboxToBoolean((Object)tuple22._2())) {
210+
return true;
211+
}
212+
bl = bl2;
213+
}
214+
if (!bl) {
215+
if (false != BoxesRunTime.unboxToBoolean((Object)tuple22._2())) return false;
216+
return true;
217+
}
218+
}
219+
return false;
220+
}
221+
```
222+
223+
You can clearly see that it's shorter ;-) and it actually does less work.
224+
If you additionally enable local optimizations, you get a pretty good code:
225+
226+
```
227+
// output of 0.2.0-RC1 with -optimise
228+
229+
public int foo(Object x) {
230+
int n;
231+
Tuple2 tuple2;
232+
CC cC;
233+
Object object;
234+
if (x instanceof CC && 1 == (n = (cC = (CC)x)._1()) && (object = cC._2()) instanceof CC) {
235+
((CC)object)._1();
236+
tuple2 = new Tuple2((Object)BoxesRunTime.boxToInteger((int)1), (Object)BoxesRunTime.boxToInteger((int)2));
237+
} else {
238+
tuple2 = new Tuple2((Object)BoxesRunTime.boxToInteger((int)42), (Object)BoxesRunTime.boxToInteger((int)43));
239+
}
240+
Tuple2 tuple22 = tuple2;
241+
return BoxesRunTime.unboxToInt((Object)tuple22._1()) + BoxesRunTime.unboxToInt((Object)tuple22._2());
242+
}
243+
244+
public boolean booleans(Object a) {
245+
boolean bl = a instanceof CC;
246+
boolean bl2 = a instanceof List;
247+
new Tuple2((Object)BoxesRunTime.boxToBoolean((boolean)bl), (Object)BoxesRunTime.boxToBoolean((boolean)bl2));
248+
new Tuple2((Object)BoxesRunTime.boxToBoolean((boolean)bl), (Object)BoxesRunTime.boxToBoolean((boolean)bl2));
249+
if (bl && bl2) {
250+
return true;
251+
}
252+
boolean bl3 = bl;
253+
if (bl3) return false;
254+
if (bl2) return false;
255+
return true;
256+
}
257+
```
258+
259+
This code still has a major inefficiency: it allocates tuples.
260+
We plan to continue migration of local optimizations from Dotty linker that should allow us to generate code that is as
261+
good the one generated by Dotty linker with global analysis disabled:
262+
263+
```
264+
// output of Dotty linker https://github.com/dotty-linker/dotty/tree/opto
265+
public int foo(Object x) {
266+
CC cC;
267+
int n = 0;
268+
int n2 = 0;
269+
if (x instanceof CC && 1 == (cC = (CC)x)._1() && cC._2() instanceof CC) {
270+
n = 1;
271+
n2 = 2;
272+
} else {
273+
n = 42;
274+
n2 = 43;
275+
}
276+
return n + n2;
277+
}
278+
279+
public boolean booleans(Object a) {
280+
boolean bl = a instanceof CC;
281+
boolean bl2 = a instanceof List;
282+
if (bl && bl2 || !bl && !bl2) {
283+
return true;
284+
}
285+
return false;
286+
}
287+
288+
```
289+
290+
## How can you try it out?
291+
We ship with tools that help you try out the Dotty platform:
292+
293+
- [IDE features for Visual Studio Code](http://dotty.epfl.ch/docs/usage/ide-support.html)
294+
- [sbt support, including retro-compatibility with Scala 2](https://github.com/lampepfl/dotty-example-project)
295+
296+
297+
You have several alternatives: use the `sbt-dotty` plugin, get a standalone
298+
installation, or try it online on [Scastie].
299+
300+
### sbt
301+
Using sbt 0.13.13 or newer, do:
302+
303+
```
304+
sbt new lampepfl/dotty.g8
305+
```
306+
307+
This will setup a new sbt project with Dotty as compiler. For more details on
308+
using Dotty with sbt, see the
309+
[example project](https://github.com/lampepfl/dotty-example-project).
310+
311+
### Standalone installation
312+
313+
Releases are available for download on the _Releases_
314+
section of the Dotty repository:
315+
https://github.com/lampepfl/dotty/releases
316+
317+
We also provide a [homebrew](https://brew.sh/) package that can be installed by running
318+
319+
```
320+
brew install lampepfl/brew/dotty
321+
```
322+
323+
### Scastie
324+
325+
[Scastie], the online Scala playground,
326+
supports Dotty.
327+
You can try it out there without installing anything.
328+
329+
330+
## What are the next steps?
331+
332+
Over the coming weeks and months, we plan to work on the following topics:
333+
334+
- [Add support for using Dotty generated classes with Scala 2.12](https://github.com/lampepfl/dotty/pull/2827)
335+
- [Add Language-level support for HMaps and HLists](https://github.com/lampepfl/dotty/pull/2199);
336+
- Upstream more optimizations from Dotty Linker
337+
338+
If you want to get your hands dirty with any of this, now is a good
339+
moment to get involved! Join the team of contributors, including
340+
Martin Odersky ([@odersky](https://twitter.com/odersky))
341+
Dmitry Petrashko ([@DarkDimius](https://twitter.com/DarkDimius)),
342+
Guillaume Martres ([@smarter](https://github.com/smarter)),
343+
Felix Mulder ([@felixmulder](https://twitter.com/felixmulder)),
344+
Nicolas Stucki ([@nicolasstucki](https://github.com/nicolasstucki)),
345+
Liu Fengyun ([@liufengyun](https://github.com/liufengyun)),
346+
Olivier Blanvillain ([@OlivierBlanvillain](https://github.com/OlivierBlanvillain)),
347+
and others!
348+
349+
## Library authors: Join our community build
350+
351+
Dotty now has a set of libraries that are built against every nightly snapshot.
352+
Currently this includes scalatest, squants and algebra.
353+
Join our [community build](https://github.com/lampepfl/dotty-community-build)
354+
to make sure that our regression suite includes your library.
355+
356+
357+
To get started, see <https://github.com/lampepfl/dotty>.
358+
359+
360+
[Scastie]: https://scastie.scala-lang.org/?target=dotty

0 commit comments

Comments
 (0)