Sunday, January 13, 2013

Upgrading to Scala 2.10.0

Scala 2.10.0 came out recently. It has many nice features I haven't used yet, for instance type tags, and production versions of many nice features that I was already using, for instance type Dynamic, implicit conversions, and reflective calls. I upgraded my main project to it and found it to be relatively painless.

My upgrade involved the following corresponding updates:
  • Updating my SBT version. I had been using an older version of the SBT build tool (0.7.7), so I upgraded that to 0.12.1. (Any version higher than 0.11.0 should work.) This was the most painful of all since SBT has changed the way its build files work. The new SBT build system is simple, so it was mostly a matter of figuring out which variables to set and how.
  • Updating library versions. The only dependency that affected me was that Scala 2.10.0 uses ScalaTest 1.9 instead of 1.8.
  • Updating compiler options. Type Dynamic, implicit conversions, and reflective calls are no longer experimental and now correspond to the flags "-language:dynamics," "-language:implicitConversions", and "-language:reflectiveCalls." I also added the "-feature" flag for a reason I can't remember. A small other thing is that I had to define a selectDynamic function in addition to applyDynamic for types extending Dynamic.
  • Cross-version packaging. I still compile a Scala 2.9.0-1 binary for my other project because it uses Scalatra 2.0.0--although 2.0.5-SNAPSHOT is supposedly compatible with Scala 2.10.0. SBT provides nice support cross-version compilation: define your versions, make sure you declare the right dependencies based on the Scala version, and then just use "+ package" to produce binaries for all Scala versions. Here are my build.sbt lines corresponding to that:
     crossScalaVersions := Seq("2.9.0-1", "2.10.0")  
     libraryDependencies <+= scalaVersion(v => v match {  
      case "2.9.0-1" => "org.scalatest" %% "scalatest" % "1.8" % "test"  
      case "2.10.0" => "org.scalatest" %% "scalatest" % "1.9" % "test"  
     })  
     scalacOptions <++= scalaVersion map (v => v match {  
      case "2.9.0-1" => Seq("-deprecation", "-unchecked", "-Xexperimental")  
      case "2.10.0" => Seq("-deprecation", "-unchecked", "-language:dynamics", "-language:implicitConversions", "-language:reflectiveCalls", "-feature")  
     })  
    

For your versioning needs, you may want to investigate this version investigator that Paul Phillips wrote.

And finally, aquestion for my Scala-using friends: I have been hesitant to upgrade to Scalatra 2.2.0. Anybody have a pointer to a summary of the concrete changes I need to make to port my code?

No comments: