You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: hand-written.md
+52-11Lines changed: 52 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -36,46 +36,87 @@ We hope to address the following in a future 2.12.x release:
36
36
Scala 2.12 is all about making optimal use of Java 8's new features (and thus generates code that requires a Java 8 runtime).
37
37
- Traits ([#5003](https://github.com/scala/scala/pull/5003)) and functions are compiled to their Java 8 equivalents. The compiler no longer generates trait implementation classes (`T$class.class`) and anonymous function classes (`C$$anonfun$1.class`).
38
38
- We treat Single Abstract Method types and Scala's builtin function types uniformly from type checking to the back end ([#4971](https://github.com/scala/scala/pull/4971)).
39
-
- In addition to compiling lambdas, we also use `invokedynamic` for a more natural encoding of other language features ([#4896](https://github.com/scala/scala/pull/4896)).
39
+
- In addition to compiling functions, we also use `invokedynamic` for a more natural encoding of other language features ([#4896](https://github.com/scala/scala/pull/4896)).
40
40
- We've standardized on the GenBCode back end ([#4814](https://github.com/scala/scala/pull/4814), [#4838](https://github.com/scala/scala/pull/4838)) and the flat classpath implementation is now the default ([#5057](https://github.com/scala/scala/pull/5057)).
41
41
- The optimizer has been completely overhauled for 2.12.
42
42
43
43
Except for the breaking changes listed below, code that compiles on 2.11.x without deprecation warnings should compile on 2.12.x too, unless you use experimental APIs such as reflection. If you find incompatibilities, please [file an issue](https://issues.scala-lang.org). Cross-building is a one-line change to most sbt builds, and even provides support for [version-specific source folders](http://www.scala-sbt.org/0.13/docs/sbt-0.13-Tech-Previews.html#Cross-version+support+for+Scala+sources) out of the box, when necessary to work around incompatibilities (e.g. macros).
44
44
45
45
### New features
46
46
47
-
Here are the [most noteworthy pull request](https://github.com/scala/scala/pulls?utf8=%E2%9C%93&q=%20is%3Amerged%20label%3A2.12%20label%3Arelease-notes%20) of the 2.12 release. See also the [RC2](http://scala-lang.org/news/2.12.0-RC2) and [RC1](http://scala-lang.org/news/2.12.0-RC1) release notes for the most recent changes.
48
-
47
+
The upcoming sections introduce new features and breaking changes in Scala 2.12 in more detail.
48
+
To understand more technicalities and review past discussions, you can also take a look at the full list of
With Java 8 allowing concrete methods in interfaces, Scala 2.12 is able to compile a trait to a single interface. Before, a trait was represented as a class that held the method implementations and an interface. Note that the compiler still has quite a bit of magic to perform behind the scenes, so that care must be taken if a trait is meant to be implemented in Java. (Briefly, if a trait does any of the following its subclasses require synthetic code: defining fields, calling super, initializer statements in the body, extending a class, relying on linearization to find implementations in the right super trait.)
54
+
With Java 8 allowing concrete methods in interfaces, Scala 2.12 is able to compile a trait to a single interface classfile.
55
+
Before, a trait was represented as an interface and a class that held the method implementations.
56
+
57
+
Note that the compiler still has quite a bit of magic to perform behind the scenes, so that care must be taken if a trait is meant to be implemented in Java.
58
+
Briefly, if a trait does any of the following its subclasses require synthetic code: defining fields, calling super, initializer statements in the body, extending a class, relying on linearization to find implementations in the right super trait.
53
59
54
60
#### Java 8-style lambdas
55
61
56
62
Scala 2.12 emits closures in the same style as Java 8, whether they target a `FunctionN` class from the standard library or a user-defined Single Abstract Method (SAM) type. The type checker accepts a function literal as a valid expression for either kind of "function-like" type (built-in or SAM). This improves the experience of using libraries written for Java 8 in Scala.
57
63
58
-
For each lambda the compiler generates a method containing the lambda body, and emits an `invokedynamic` that will spin up a lightweight class for this closure using the JDK's `LambdaMetaFactory`.
64
+
For each lambda the compiler generates a method containing the lambda body, and emits an `invokedynamic` that will spin up a lightweight class for this closure using the JDK's `LambdaMetaFactory`. Note that in the following situations, the an anonymous function class is still synthesized at compile-time:
65
+
66
+
- If the SAM type is not a simple interface, for example an abstract class or a triat with a field definition (see [#4971](https://github.com/scala/scala/pull/4971))
67
+
- If the abstract method is specialized - except for `scala.FunctionN`, whose specialized variants can be instantiated using `LambdaMetaFactory` (see [#4971](https://github.com/scala/scala/pull/4971))
68
+
- If the function literal is defined in a constructor or a super call ([#3616](https://github.com/scala/scala/pull/3616))
59
69
60
70
Compared to Scala 2.11, the new scheme has the advantage that, in most cases, the compiler does not need to generate an anonymous class for each closure. This leads to significantly smaller JAR files.
61
71
62
72
#### New back end
63
73
64
-
Scala 2.12 standardizes on the "GenBCode" back end, which emits code more quickly because it directly generates ASM bytecode from Scala compiler trees, while the previous back end used an intermediate representation called "ICode". The old back ends (GenASM and GenIcode) have been removed ([#4814](https://github.com/scala/scala/pull/4814), [#4838](https://github.com/scala/scala/pull/4838)).
74
+
Scala 2.12 standardizes on the "GenBCode" back end, which emits code more quickly because it directly generates bytecode from Scala compiler trees, while the previous back end used an intermediate representation called "ICode".
75
+
The old back ends (GenASM and GenIcode) have been removed ([#4814](https://github.com/scala/scala/pull/4814), [#4838](https://github.com/scala/scala/pull/4838)).
76
+
77
+
65
78
66
79
#### New optimizer
67
80
68
-
The GenBCode back end includes a new inliner and bytecode optimizer.
69
-
The optimizer is enabled using `-opt` compiler option, which defaults
70
-
to `-opt:l:classpath`. Check `-opt:help` to see the full list of
71
-
available options for the optimizer.
81
+
The GenBCode back end includes a new inliner and bytecode optimizer. The optimizer is configured
82
+
using `-opt` compiler option, by default it removes unreachable code within a method. Check
83
+
`-opt:help` to see the list of available options for the optimizer.
72
84
73
85
The following optimizations are available:
74
86
75
87
* Inlining final methods, including methods defined in objects and final methods defined in traits
76
88
* If a closure is allocated and invoked within the same method, the closure invocation is replaced by an invocations of the corresponding lambda body method
77
89
* Dead code elimination and a small number of cleanup optimizations
* Box/unbox elimination [#4858](https://github.com/scala/scala/pull/4858): primitive boxes and tuples that are created and used within some method without exscaping are eliminated.
91
+
92
+
For example, the following code
93
+
94
+
```scala
95
+
deff(a: Int, b: Boolean) = (a, b) match {
96
+
case (0, true) =>-1
97
+
case _ if a <0=>-a
98
+
case _ => a
99
+
}
100
+
```
101
+
102
+
produces, when compiled with `-opt:l:method`, the following bytecode (decompiled using cfr-decompiler):
103
+
104
+
```java
105
+
publicint f(int a, boolean b) {
106
+
int n =0== a &&true== b ?-1: (a <0?- a : a);
107
+
return n;
108
+
}
109
+
```
110
+
111
+
The optimizer supports inlining (disabled by default). With `-opt:l:project`, only code from source files currently being compiled is inlined, while `-opt:l:classpath` enables inlining code from libraries on the compiler's classpath. Other than methods marked [`@inline`](http://www.scala-lang.org/files/archive/api/2.12.0/scala/inline.html), higher-order methods are inlined if the function argument is a lambda, or a parameter of the callee.
112
+
113
+
Note that:
114
+
- We recommend to enable inlining only for production builds, sbt's incremental compilation does not track dependencies caused by inlining.
115
+
- When inlining code from the classpath, you need to ensure that all dependencies have exactly the same versions at compile time and run time.
116
+
117
+
The Scala distribution is built using `-opt:l:classpath`, which improves the performance of the Scala compiler by roughly 5% (hot and cold, measured using our [JMH-based benchmark suite](https://github.com/scala/compiler-benchmark/blob/master/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala)).
118
+
119
+
The GenBCode backend and the implementation of the new optimizer are built on earlier work by Miguel Garcia.
0 commit comments