[Scala] Scala 2.10 Feature -- Modularized Language Features

Scala 2.10.0

Scala 2.10.0 is released in January, which included a lot of new features. But due to my busy daily work, I don't have a chance to take a look on it until this weekend.

Since Lift web framework has supported Scala 2.10.0 in version 2.5, so I tried to upgrad my project called BeDone to Scala 2.10.0, and make a note about Modularized Language Features in Scala 2.10.0 here.

Modularized Language Features

During upgrade to Scala 2.10.0, the most obvious thing is that the compiler yield a lot of warning which I don't have it when I was using Scala 2.9 to compile my project. The program still works fine, but those warning is annoying.

For example, a simple Scala program like the following code:

object Test
{
    case class Point(x: Int, y: Int)

    implicit def toPoint(cord: (Int, Int)) = Point(cord._1, cord._2)

    def main(args: Array[String])
    {
        val point: Point = (0, 0)

        println(point)
    }
}

It will cause warning during compile, and if you add -feature to compiler options, it will tell you that you're defineing implicit conversion method, and you should enable it.

brianhsu@USBGentoo ~/test/src/main/scala $ scalac Test.scala
warning: there were 1 feature warnings; re-run with -feature for details
one warning found
brianhsu@USBGentoo ~/test/src/main/scala $ scalac -feature Test.scala
Test.scala:4: warning: implicit conversion method toPoint should be enabled
by making the implicit value language.implicitConversions visible.

We have this warning because Scala 2.10.0 introduced a new concept called Modularized Language Features, which means it break down Scala language to features, and you could control which features you want to use.

After all, there are lots of debate about whether Scala is too complex and have too many advance features that could be used incorrectly. To solve this problem, Scala 2.10.0 adds Modularized Language Features design, which means you could control what subset of Scala you want to use.

Using only subset of certain programming language is not something new, for example, in the book JavaScript: The Good Parts the author argued that we should only use the Good Part subset of JavaScript.

Modularized Language Features in Scala 2.10 just make this concept more explicity, if you are using some advance features that you didn't plan to, the compiler will warn you.

In our example, defineing a new implicit conversion method is considered advance feature, so if we want to use it, we need tell Scala compiler explicitly that we know what we are doing.

There are two ways to achieve this, the first one is import those advance feature at our source code, the features are defined in scala.language object.

/*
 * I know I'm defineing a new implicit conversion, don't stop me!
 */
import language.implicitConversions

object Test
{
    implicit def toPoint(cord: (Int, Int)) = Point(cord._1, cord._2)

    case class Point(x: Int, y: Int)

    def main(args: Array[String])
    {
        val point: Point = (0, 0)

        println(point)
    }
}

After add the import statement, we won't have any warning anymore, because we have told compiler that this is exaclty what we want.

But there is a problem about this apporach, the code above is no longer able to compile at Scala 2.9, because Scala 2.9 has no object named scala.language.

But don't worry, Scala 2.10.0 also provides anthoer way to tell compiler which feature you want to use, through the compiler options. We just need to add options like -language:[feature] to compiler when we emit the compile commands.

brianhsu@USBGentoo ~/test/src/main/scala $ scalac -language:implicitConversions Test.scala
brianhsu@USBGentoo ~/test/src/main/scala $ scala Test
Point(0,0)

That's all, after we add the option to compiler, we could tell Scala compiler that we want to enable implicit conversion method without modifiy our source code.

回響