Friday, August 26, 2011

Is Scala worthy of your trust?

The Scala language offers significant improvements over the Java language with traits, higher order functions and type inference among other powerful features. At the same time, Scala still allows for seamless import and use of existing classes written in Java. You can migrate to Scala piecemeal, for example in your test classes at first and then migrate larger and larger chunks of code.

However, there is one aspect to the Scala language which I find deeply annoying. Scala keeps breaking binary compatibility with every new release. In spite of previous promises, compatibility was broken in release 2.7, broken again in release 2.8 and broken yet again in 2.9. As I understand it, Scala language designers are forced to breaking compatibility whenever Scala library traits change in an incompatible way.

When a binary breakage occurs at the language level, the whole ecosystem for the language has to align itself with the new release. This is an extremely painful process affecting all users of the language. Even if a user does not want to upgrade to the latest and greatest Scala release, as long as a single tool, say T, in the tool-chain of the user upgrades and the user upgrades to the new version of T, then kaboom! All other project dependencies need to be upgraded as well.

If you decide to upgrade to the newest version of Scala in your project, you will also need to update every single dependency in your project (written in Scala). If you are lucky and every single dependency has made a release for the latest version of Scala, your project will build fine after the update. Otherwise, if a single dependency has not made the required release, you are left with two relatively unpleasant choices. You can either revert to the previous version of Scala or remove the non-compliant dependency.

If the Scala update was triggered by an IDE update, reverting to the older version of Scala may be particularly painful. If removing the non-compliant dependency is impossible, you will be hung out to dry.

As noted earlier, Scala language designers break compatibility for good technical reasons related to traits. The language is improved and cleaned up with every version, unlike Java which accumulates cruft. In other words, there is a good side to breaking compatibility. Preserving compatibility is an immensely intricate problem with a wide range of consequences. However, it is ultimately a political decision balancing between stability and change.

Once you have tasted the expressive power of Scala, it is hard to go back to program in Java. Once you have tasted the stability of Java, it is hard to put up with the brittleness of Scala. It's a non-ideal world out there.

Tooling proposed by Typesafe detects breakages and ensuring compatibility in minor versions. This tool is similar to clirr which has been around for a long time. Typesafe's response to the binary compatibility issue confirms my suspicions that the issue is still largely misunderstood by Typesafe. Typesafe subscription, the Migration manager or taking over a larger set of core libraries by Typesafe do not ensure that upgrading a project to the next version of Scala will go smoothly.

Assuming Scala continues to break compatibility in the foreseeable future, then I'll go out on a limb and make the following predictions:

The current situation limits the Scala user-base to a relatively small niche of enthusiasts. The small user-base hinders the development of a large Scala eco-system which further limit growth of the user-base, creating a vicious cycle.

Apparently, only few people complain about Scala's existing compatibility policy. Presumably, the Scala community has entered a comfort zone where existing users have grown accustomed to the current situation. For example, SBT makes it easy for authors of Scala libraries to generate artifacts for multiple versions of Scala. However, SBT is not suitable for projects which offer Scala-based extensions but otherwise are centered around Java. Thus, Scala's current compatibility policy makes it hard for Java projects to offer Scala-based extensions. I, for one, would love to offer a Scala-based configurator for logback (in addition to XML and Groovy based configurators) but have no intention of migrating our build to SBT.

One might also forget that the vast vast majority of developers will vote with their feet. They will simply walk away instead of engaging the Scala community for the preservation of binary compatibility. This, Scala will probably continue to be attractive for projects where occasional compatibility breakages are acceptable. Of course, the set of projects where breakages are unacceptable is... non-negligible.

The upcoming Java 8 with support closures will be a big leap forward for the Java platform. Competing languages will eventually close the gap, and Scala will stop being cool.