I've written a rather large program in Scala 2.7.5, and now I'm looking forward to version 2.8. But I'm curious about how this big leap in the evolution of Scala will affect me.
What will be the biggest differences between these two versions of Scala? And perhaps most importantly:
When you migrate, the compiler can provide you with some safety nets.
-deprecation
, and follow the recommendations from all deprecation warnings. Update your code to use unnnested packages. This can be done mechanically by repeatedly running this regular expression search replace.
s/^(package com.example.project.*)\.(\w+)/$1\npackage $2/g
Compile with 2.8.0 compiler, using paranoid command line options -deprecation -Xmigration -Xcheckinit -Xstrict-warnings -Xwarninit
If you receive errors the error could not find implicit value for evidence parameter of type scala.reflect.ClassManifest[T]
, you need to add an implicit parameter (or equivalently, a context bound), on a type parameter.
Before:
scala> def listToArray[T](ls: List[T]): Array[T] = ls.toArray <console>:5: error: could not find implicit value for evidence parameter of type scala.reflect.ClassManifest[T] def listToArray[T](ls: List[T]): Array[T] = ls.toArray ^
After:
scala> def listToArray[T: Manifest](ls: List[T]): Array[T] = ls.toArray listToArray: [T](ls: List[T])(implicit evidence$1: Manifest[T])Array[T] scala> def listToArray[T](ls: List[T])(implicit m: Manifest[T]): Array[T] = ls.toArray listToArray: [T](ls: List[T])(implicit m: Manifest[T])Array[T]
Any method that calls listToArray
, and itself takes T
as a type parameter, must also accept the Manifest as an implicit parameter. See the Arrays SID for details.
Before too long, you'll encounter an error like this:
scala> collection.Map(1 -> 2): Map[Int, Int] <console>:6: error: type mismatch; found : scala.collection.Map[Int,Int] required: Map[Int,Int] collection.Map(1 -> 2): Map[Int, Int] ^
You need to understand that the type Map
is an alias in Predef for collection.immutable.Map
.
object Predef { type Map[A, B] = collection.immutable.Map[A, B] val Map = collection.immutable.Map }
There are three types named Map
-- a read-only interface: collection.Map
, an immutable implementation: collection.immutable.Map
, and a mutable implementation: collection.mutable.Map
. Furthermore, the library defines the behaviour in a parallel set of traits MapLike
, but this is really an implementation detail.
Use the generated copy
method of case classes.
scala> case class Foo(a: Int, b: String) defined class Foo scala> Foo(1, "a").copy(b = "b") res1: Foo = Foo(1,b)
List
to Seq
or Iterable
or Traversable
. Because collection classes are in a clean hierarchy, can you accept a more general type.There are many other new features that can be safely ignored as you start migrating, for example @specialized
and Continuations.
You can find here a preview of new feature in Scala2.8 (April 2009), completed with recent this article (June 2009)
"Rewriting code" is not an obligation (except for using some of the improved Collections), but some features like continuation (Wikipedia: an abstract representation of the control state, or the "rest of computation" or "rest of code to be executed") can give you some new ideas. A good introduction is found here, written by Daniel (who has also posted a much more detailed and specific answer in this thread).
Note: Scala on Netbeans seems to work with some 2.8 nightly-build (vs. the official page for 2.7.x)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With