Montag, 17. März 2008

A closer look at Scala

So I have been reading more about Scala recently and it has been interesting reads so far.  As I consider myself a "Java-Refugee" I  was surprised to find this [1]. Scala surely has some different concepts some of them I want to write down here.


Methods
A few examples of method declarations:

//this method does nothingdef firstName() = {
 var back:String ="empty"
}

//this method doesn't do eitherdef firstName() = {
 var back:String ="empty"
 back = "still nothing"
}

//finally return the back variable
def firstName() = {
 var back:String ="empty"
 back
}

//declare the return type explicitly 
def firstName():String = {
 var back:String ="empty"
 back 
}
Note here in the last example that the last statement in the method is returned. It is also possible to use "return back" instead of just "back". The second example fails to return a value because the last line contains an assignment.
If you wanted to override a method in a subclass you have to declare it explicit via the override modifier.


Closures
Lastly a short example of Closures (=>), which offer a very nice alternative to anonymous inner classes in java:

val arr = Array(1, 2, 3, 4, 5)
val sum = arr.reduceRight((a:Int, b:Int) => a + b)


println(sum)
So reduceRight is a method which takes two values as parametes from the array(arr) and awaits a result originating from an operation involving these two parameters. So simply in this case, our result value sum will contain a sum over all elements of the value arr. 


Statics in Scala
There is no static keyword in Scala. Instead the concept of a Singleton is applied through the object keyword. If a class and an object have the same name the latter is described as companion object. 
Pattern matching
Pattern matching seems at a very first glance related to the switch statement in java, but there are so many differences and it turn out to be much more useful.   
Java:

int number= ..
String res="";

  switch (number) {
   case 1: res="ONE"; break;
   case 2: res="TWO"; break;
   case 3: res="THREE";  break;
   default: res=" i don't know";
 }

Scala:


val number=..
val res=""


res = i match{
   case 1 => "ONE"
   case 2 => "TWO"
   case 3 => "THREE"
   case _ => " i don't know"
}


Scala's case statement can't fall through, you don't have to use a break statement like in Java. The pattern matching is not restricted to primitives (int in java) you may use any type or object. 
Case classes
Note here that the underscore "_" has different meanings, so it should be used carefully and depending on the context in its.
Some Random thoughts pending:


Exceptions
Scala does not have the concept of checked exceptions. While this makes method declarations cleaner (IMHO), you have to take care of it either way. Since pattern matching works on types you can do nice things like this:


try {
..
} catch {
case e:SQLException => println(”Database error”)
case e:MalformedURLException => println(”Bad URL”)
case e:_ => println(”any other Error”)

}
Traits
Traits provide a mix-in mechanism which is similar to multiple inheritance but avoids some pitfalls like the diamond problem through a linearization mechanism. But still traits seem like a heavy topic since you have to think about initialization order. What I really like about traits is that you can attach or mix-in traits dynamically into an class:
trait funny { def saySome() = "hoho"}
class silent{}


val s= new silent() with funny
s.saySome //prints "hoho"


So you can put in Code in existing classes with extending them. I find this very interesting.
Left random Notes:




  • class names don't have to match filenames
  • While in Java you have only interfaces and classes in Scala you have 3 basic entities: classes, traits and objects
  • the constructor concept seems a little awkward since you write it directly in the class definition
  • imports can be scoped, this is pretty nice e.g. if you want to limit an important to an inner method