Monday, October 22, 2007

Fun With Scala: Things I'm Learning From Lift #2

Thanks to astute reader Ken (Author's Note: I have a reader! An astute one! Who knew?!), I learned something about a feature I was bragging about in my last post; namely, the ability to import members of a class. As it turns out, not only is this feature present in Java 5 -- see the documentation for static imports -- the Scala version of it is pretty much equivalent.

Ken points out that my example of lift importing the members of the net.liftweb.util.Helpers "class" maps exactly to the corresponding Java import. I waved my hands around the fact that Helpers is actually an object, which is, simultaneously and at the same time, Scala's way of denoting a singleton and providing static members (all of the members of an object are effectively static). But it turns out that the import syntax I was bragging about works precisely because Helpers is an object and not a class.

Here's some lame, contrived, forced-example, somewhat-minimal Scala code to demonstrate:

Mixee.scala

package bogus;

class Mixee {
def weird: String = {"Weird Al!"}
def twentySeven: String = {"27!"}
}


Mixer.scala

package bogus;

import Mixee._;

object Mixer {
def main(args: Array[String]): Unit = { Console.println(weird); Console.println(twentySeven) }
}

As described here, Mixer.scala will refuse to compile, with the error: "not found: value Mixee". This is because Mixee is defined as a class. Change class to object and it compiles (and runs) just fine.

Bonus Discovery: While researching this, I also learned that Eclipse with the Scala plugin is not as smart as it should be about building my bogus project. If I start with a clean compile (i.e., defining Mixee as an object), Eclipse is happy. If I then change the definition of Mixee from object to class, the error doesn't show up until I force a rebuild by selecting Project -> Clean... If I then change class back to object, the error goes away without my forcing the rebuild.

Anyone got a line on that? Ken? Anyone?

Anyway, just for the record, my purpose with these posts is not to bury Java, but to praise Scala and learn how it's different. I'll leave the determination of whether Scala is "better" than Java up to you, my readers. Both of you (hi, Mom!). ;-)

2 comments:

Steve Bendiola said...

one powerful feature of Scala's import is aliasing:

Welcome to Darwin!
computer:~ user$ scala
Welcome to Scala version 2.6.0-final.
Type in expressions to have them evaluated.
Type :help for more information.

scala> import java.util.{ArrayList => SomeOtherName}
import java.util.ArrayList=>SomeOtherName

scala> val x = new SomeOtherName
x: java.util.ArrayList = []

scala> x add 3
res0: Boolean = true

scala> println(x)
[3]

scala> import x._
import x._

scala> add(5)
res3: Boolean = true

scala> println(x)
[3, 5]

Arrgh said...

You may also want to make use of Scala's type inference; I believe this is a minimal version of your Mixee class:

class Mixee {
def weird = "Weird Al!"
def twentySeven = "27!"
}