Blog

April 21, 2014

Scala 2.11 Has Arrived!

Try it out now in Activator, or download a classic distribution. Many open source projects have already upgraded to Scala 2.11. If your upgrade from 2.10 to 2.11 involves more than simply recompiling, let us know and we will do our best to fix it. (Restrictions apply; fine print: assuming your code compiled without deprecation warnings, and your dependencies are available for 2.11).

The Scala 2.11 series targets Java 6, with (evolving) experimental support for Java 8. In 2.11, Java 8 support is mostly limited to reading Java 8 bytecode and parsing Java 8 source. We will be expanding Scala's (experimental) Java 8 support and interop throughout the 2.11 series.

The Scala team and contributors fixed well over 600 bugs in Scala 2.11! As many fixes as possible were back ported to 2.10. With the arrival of 2.11, the 2.10 series goes into maintenance mode, and will likely conclude by the end of 2014 with version 2.10.5, two years after the initial 2.10.0 release.

A big thank you to everyone who has helped improve Scala by reporting bugs, improving our documentation, participating in mailing lists and other public fora, and -- of course -- submitting and reviewing pull requests! You are all awesome.

2.11 highlights

In addition to the bug fixes and improvements made in the 2.10 series, 2.11's development is organized around three themes:

Smaller

We moved a fifth (of the bytecode) of the core Scala library to separate modules. We hope this will foster diversity in the Scala eco-system and speed up evolution of these modules, while stabilizing Scala's core. The ultimate goal is binary compatibility between major versions of Scala's core. A nice side-effect was a significant reduction of the size of the JavaScript produced by scala.js.

To compensate for the split, we introduced the virtual scala-library-all artifact to aggregate the modules that constitute the official Scala release. If your project was using functionality that moved to a module (xml, parser-combinators, swing, continuations), here's how to update your build (sbt/maven).

As we work towards making the Scala compiler a platform itself (currently extensible via compiler plugins and macros), we have internally modularized the compiler, and removed several obsolete parts (the experimental .NET backend, the pre-2.10 pattern matcher, and bytecode emitter). Improving scalac-the-platform remains an important focus for us in 2.12.

Faster

Compiler performance

Grzegorz implemented a new scheme for incremental compilation, which significantly improves performance while maintaining accuracy. To try it out, upgrade to sbt 0.13.2 and add incOptions := incOptions.value.withNameHashing(true) to your build! Other build tools are also supported. More info at this sbt issue -- that's where most of the work happened. Further performance enhancements are planned.

Jason worked on optimizing the batch compiler's performance. We will continue to work on this during the 2.11 cycle.

We have started integrating the new (experimental) GenBCode back-end, but have not yet merged the optimizer. This effort will continue during the 2.11 series, with a focus on a well-tested and predictable optimizer and solid Java 8 support. See Miguel's extensive documentation.

James implemented a new (experimental) way of compiling closures: under -Ydelambdafy:method, anonymous functions are compiled faster, with a smaller bytecode footprint, mimicking Java 8-style closures as closely as possible on Java 6. This works by lifting the closure body to a private method (also marked static if no thisreference is needed) of the enclosing class. At the last moment during compilation, we emit a small anonymous class that extends FunctionN and delegates to this method. On Java 8, this step will be replaced by a emitting a call to LambdaMetaFactory.

James also implemented branch elimination through constant analysis (#2214).

Stabler

Code that compiled on 2.10 without deprecation warnings should compile on 2.11 (we do not guarantee this for experimental APIs, such as reflection). The Scala team at Typesafe verified this by dbuilding (developed by Antonio Cunei) over 900 thousands lines of Scala code taken from a sizable number of open source projects on a nightly basis.

Many classes and methods in the collections library have been slated to become final in 2.12, to clarify which classes are not meant to be subclassed and to facilitate future maintenance and performance improvements

SI-7475 Improvements to access checks, aligned with the spec (see also the linked issues). Most importantly, private members are no longer inherited. Thus, this does not type check: class Foo[T] { private val bar: T = ???; new Foo[String] { bar: String } }, as the bar in bar: String refers to the bar with type T. The Foo[String]'s bar is not inherited, and thus not in scope, in the refinement. (Example from SI-8371, see also SI-8426.)

The following changes were made after a deprecation cycle (Thank you, Simon, for leading the deprecation effort!)

#3103, #3191, #3582 Collection classes and methods that are (very) difficult to extend safely have been slated for being marked final. Proxies and wrappers that were not adequately implemented or kept up-to-date have been deprecated, along with other minor inconsistencies.

scala-actors is now deprecated and will be removed in 2.12; please follow the steps in the Actors Migration Guide to port to Akka Actors

We are looking for maintainers to take over the following modules: scala-swing, scala-continuations. 2.12 will not include them if no new maintainer is found. We will likely keep maintaining the other modules (scala-xml, scala-parser-combinators), but help is still greatly appreciated.

Deprecation is closely related to source and binary compatibility. We say two versions of Scala are source compatible when they compile the same programs with the same results. Deprecation requires qualifying this statement: "assuming there are no deprecation warnings". This is what allows us to evolve the Scala platform and keep it healthy. We move slowly to guarantee smooth upgrades, but we want to keep improving as well!

Binary Compatibility

When two versions of Scala are binary compatible, it is safe to compile your project on one Scala version and link against another Scala version at run time. Safe run-time linkage (only!) means that the JVM does not throw a (subclass of) LinkageError when executing your program in the mixed scenario, assuming that none arise when compiling and running on the same version of Scala. Concretely, this means you may have external dependencies on your run-time classpath that use a different version of Scala than the one you're compiling with, as long as they're binary compatible. In other words, separate compilation on different binary compatible versions does not introduce problems compared to compiling and running everything on the sample version of Scala.

We distinguish forwards and backwards compatibility (these are properties of a sequence of versions, not of an individual version). Maintaining backwards compatibility means code compiled on an older version will link with code compiled with newer ones. Forwards compatibility allows you to compile on new versions and run on older ones.

As in the 2.10 series, we guarantee both forwards and backwards compatibility of the "org.scala-lang" % "scala-library" % "2.11.x" and "org.scala-lang" % "scala-reflect" % "2.11.x" artifacts. Note that internal classes are exempt from this policy. Thus, we do not recommend using classes from the packages scala.reflect.internal, scala.reflect.runtime orscala.concurrent.impl.

All other artifacts, such as the new modules (artifacts under the groupId org.scala-lang.modules) are only backwards binary compatible, so that they can evolve more rapidly. The lack of forwards compatibility means that you should always have the latest version of these modules on the classpath.

From the blog

While Reactive application development is off to a roaring start and becoming mainstream, this leads to demands on Operations that are simply not met by yesterday’s software architectures and technologies. The pressure facing enterprises to manage resilient, responsive systems is brutal, yet most existing technologies available today are not designed to deploy and manage Reactive systems running on clusters. It’s due to this fact that Operations face a higher risk of downtime by using inappropriate tools/practices at a time when being unavailable is more costly than ever. So why is this happening? Well, it's not 2005 anymore–and why that's a problem for Operations is explained here...

Ten months ago we posted about architectural changes to Typesafe Activator. After a few a lot of yak shaves, side projects, and detours, we have Activator 1.3.0 based on sbt server, a new setup where multiple clients can share the same instance of sbt. sbt server is also available in ABI-stable protocol-stable form for other clients (IDEs, command line, desktop status icon, whatever you can think of) to try out.