Blog

April 21, 2014

Scala 2.11 Has Arrived!

@adriaanm
April 21, 2014
Scala

Great news everyone! Scala 2.11.0 is here!

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 IDE with this release built in is available from this update site for Eclipse 4.2/4.3 (Juno/Kepler). Please have a look at the getting started guide for more info on installing Eclipse and Scala IDE.

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.

  • Eugene improved the performance of run-time reflection (SI-6638).

Operations on collections

  • Immutable HashMaps and HashSets perform faster filters, unions, and the like, with improved structural sharing (lower memory usage or churn).
  • Rex implemented mutable LongMap and AnyRefMap that provide improved performance when keys are Long orAnyRef (performance enhancement of up to 4x or 2x respectively).
  • collective effort brought improved performance to List's mapflatMap, and collect.

Generating faster code

  • 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

  • The Scala IDE benefits from numerous bug fixes and improvements by the IDE team in the Scala compiler.

  • We invested significantly in improving our infrastructure. We cleaned up our ant build in preparation for a move to sbt in 2.12 (already the standard for the new modules), improved our release automation and simplified building a Scala distribution. Scala PR validation now tests integration with sbt and Scala IDE.

Important changes

The experimental reflection API underwent breaking changes, which luckily have an easy fix that is source compatible with Scala 2.10. The reflection/macro changelog has detailed instructions.

We've decided to fix the following more obscure deviations from specified behavior without prior deprecation.

  • SI-4577 Compile x match { case _ : Foo.type => } to Foo eq x, as specified. It used to be Foo == x (without warning). If that's what you meant, write case Foo =>.

  • 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!)

  • SI-6809 Case classes without a parameter list are no longer allowed.
  • SI-7618 Octal number literals no longer supported.

Finally, some notable improvements and bug fixes:

  • SI-7296 Case classes with > 22 parameters are now allowed.
  • SI-3346 Implicit arguments of implicit conversions now guide type inference.
  • SI-6240 Thread safety of reflection API.
  • Quasiquotes are now the recommended way of creating and dissecting Scala syntax trees.
  • #3037 Experimental support for SAM synthesis.
  • #2848 Name-based pattern-matching.
  • SI-6169 Infer bounds of Java-defined existential types.
  • SI-6566 Right-hand sides of type aliases are now considered invariant for variance checking.
  • SI-8126 Add -Xsource option (make 2.11 type checker behave like 2.10 where possible).
  • SI-5917 Improve public AST creation facilities.
  • SI-8063 Expose much needed methods in public reflection/macro API.

To catch future changes like this early, you can run the compiler under -Xfuture, which makes it behave like the next major version, where possible, to alert you to upcoming breaking changes.

Deprecations

The following language "warts" have been deprecated:

  • SI-7605 Procedure syntax (only under -Xfuture).
  • SI-5479 DelayedInit. We will continue support for the important extends App idiom. We won't drop DelayedInit until there's a replacement for important use cases. (More details and a proposed alternative.)
  • SI-6455 Rewrite of .withFilter to .filter: you must implement withFilter to be compatible with for-comprehensions.
  • SI-8035 Automatic insertion of () on missing argument lists.
  • SI-6675 Auto-tupling in patterns.
  • SI-7247 NotNull, which was never fully implemented -- slated for removal in 2.12.
  • SI-1503 Unsound type assumption for stable identifier and literal patterns.
  • SI-7629 View bounds (under -Xfuture).

We'd like to emphasize the following library deprecations:

  • #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

  • SI-7958 Deprecate scala.concurrent.future and scala.concurrent.promise

  • SI-3235 Deprecate round on Int and Long (#3581).

  • We are looking for maintainers to take over the following modules: scala-swingscala-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.internalscala.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.

For more info, check out http://scala-lang.org/ and watch last week's webinar, Welcome to Scala 2.11.

comments powered by Disqus
Browse Recent Blog Posts