I highly recommend a careful reading of "Programming in Scala" by Martin Ordesky, Lex Spoon, and Bill Venners. Read it through once to get familiar with the syntax and features, and then read it again to see how it all fits together. I find it worth emphasizing how some features should change the way a Java programmer designs and builds programs. I will assume functional features are not a novelty at this point. We have had Scheme ( http://mitpress.mit.edu/sicp/full-text/book/book.html ) and Haskell ( http://www.realworldhaskell.org/ ) for a long time to show us how functional programming is done. Scala is not a pure functional language, and that should be accepted as a feature, not as a compromise or defect. Object-oriented encapsulation of state has proven useful a long time, and we know how to scale large projects with this model. We can see how to move our projects and programmers from Java to Scala. I'll also assume that you've had time to get accustomed to some of the syntactic sugar of scala. Conciseness does not necessarily change how you program, though it can when boilerplate was previously overwhelming. * Thunking * At runtime, you can assemble a chuck of code, often called a "thunk," and pass it along to be evaluated when and if necessary. Scala supports strict evaluation of method arguments: any expressions are evaluated before they are passed. Nevertheless, you can easily prevent evaluation by passing a function that contains the expressions you want evaluated. A good example is an assert, where you only want to evaluate an expression when asserts are enabled. Java found it necessary to introduce a new keyword to support this feature. Scala does not. This function always evaluates the argument, even when disabled: ==> val assertionsEnabled = false def dumbAssert(test: Boolean) = if (assertionsEnabled && !test) throw new AssertionError dumbAssert(1>2) <== Notice that you can assign a function literal to a function value: ==> scala> val calculateTest = () => {println("calculating..."); 1 > 2} calculateTest: () => Boolean = <function0> scala> calculateTest() calculating... res0: Boolean = false scala> dumbAssert(calculateTest()) calculating <== This function retains an expression, then evaluates that expression when the function is called, even when assertions are not enabled. (Note this function literal is actually an anonymous object that extends the trait Function0. An apply method invokes the function.) Instead you can define an assert that takes a function. ==> def betterAssert(test: () => Boolean) = if (assertionsEnabled && !test()) throw new AssertionError betterAssert(() => 2>1) betterAssert(calculateTest) <== The function is called only when assertions are enabled. Passing a function is still a burden. If you try a simple expression evaluating to a boolean, you get a error because a function is expected. ==> scala> betterAssert(2>1) <console>:8: error: type mismatch; found : Boolean(true) required: () => Boolean betterAssert(2>1) <== If you omit the () from the declaration, then you are passing the argument by name, and delaying its evaluation until first used. ==> def bestAssert(test: => Boolean) = if (assertionsEnabled && !test) throw new AssertionError bestAssert(2>1) bestAssert(calculateTest()) <== You no longer see the calculation as a side-effect, when the expression does not need to be evaluated. Notice how similar this syntax is to forming and passing a function. * Currying for control * Ever find yourself copying boilerplate that you seem unable to reuse? Let's pretend the following try/catch/finally block is useful. ==> def mathTest(test: => Boolean): Unit = { try { if (!test) throw new AssertionError("Test failed"); } catch { case ae: ArithmeticException => throw new AssertionError("Bad Math"); } finally { println("Finally") } } <== It would behave like this: ==> scala> mathTest (3>2) Finally scala> mathTest (2>3) Finally java.lang.AssertionError: Test failed ... scala> mathTest (3/0>2) Finally java.lang.AssertionError: Bad Math ... <== Let's pretend you want to change the error words, and the contents of the finally. ==> def mathTest2(finalAction: => Unit, errorWords: String, test: => Boolean): Unit = { try { if (!test) throw new AssertionError(errorWords) } catch { case ae: ArithmeticException => throw new AssertionError("Bad math") } finally { finalAction } } <== You could use it like this, awkwardly: ==> scala> mathTest2(println("Pretend I'm closing a file"),"normal math", 3>2) Pretend I'm closing a file scala> mathTest2(println("Pretend I'm closing a file"),"crazy math", 1/0>2) Pretend I'm closing a file java.lang.AssertionError: Bad math ... <== Instead, you can declare a function that returns a function that returns a function. (And the first argument is a function.) ==> def mathTest3(finalAction: ()=>Unit)(errorWords: String)(test: => Boolean): Unit = { try { if (!test) throw new AssertionError(errorWords) } catch { case ae: ArithmeticException => throw new AssertionError("Bad math") } finally { finalAction() } } mathTest3: (finalAction: () => Unit)(errorWords: String)(test: => Boolean)Unit <== You can then save a new "curried" function like this: ==> val mathTest4 = mathTest3 { () => println("Never again forgetting to close that file.") } _ <== The new function ``mathTest4'' is a function that returns a function. Why did I not pass this first argument by name, instead of as a function? Because that argument is evaluated to construct the function that is returned. You can apply this as you would a control structure: ==> mathTest4 ("Normal math?") { val two = 2 val three = 3 println ("Finished with expensive calculations."); three > two } Finished with expensive calculations. Never again forgetting to close that file. <== Or perhaps not so good math: ==> mathTest4 ("Abnormal math?") { val one = 1 val infinity = 1/0 println ("Did I get away with dividing by zero?"); infinity > one } Never again forgetting to close that file. java.lang.AssertionError: Bad math ... <== * Whole lot of nothing * In Java, we have ``null'' and ``void''. In Scala we have a few more alternatives. In Scala ``null'' is actually an instance of the ``Null'' class. The ``Null'' class is a subclass of any class that derives from ``AnyRef''. So you can assign a null instance to any reference type: ==> scala> val x = null x: Null = null scala> var y = "foo" y: java.lang.String = foo scala> y = x y: java.lang.String = null scala> null == y res4: Boolean = true <== The ``=='' is a final method defined in ``Any'' ``Unit'' is like a ``void'', returned from a method that is called only for side-effects. However ``Unit'' is an actual type, with only one allowed value, written as ``()''. ==> scala> Unit res3: Unit.type = object scala.Unit scala> val unit = () unit: Unit = () scala> def foo() = println("bar") foo: ()Unit scala> assert (foo() == ()) bar <== ``Nil'' is a singleton object that corresponds to the empty list: ==> scala> Nil res2: scala.collection.immutable.Nil.type = List() scala> val list = List("a") list: List[java.lang.String] = List(a) scala> list.tail res29: List[java.lang.String] = List() scala> assert (list.tail == Nil) <== ``Nothing'' is the value returned by a method that does not return. You can use such a method where another value is expected. ==> scala> def f() = {throw new Exception("No return.")} f: () Nothing scala> var g = () => {"Returns string"} g: () => java.lang.String = <function0> scala> g = f g: () => java.lang.String = <function0> scala> g() java.lang.Exception: No return. <== ``None'' is one of two possible values for the ``Option'' type. The other possible value is ``Some(x)'', where x is a useful value. * Algebraic types * Pattern-matching in scala, is actually an object-oriented implementation of algebraic types. ``Option'' is an example. For example, we can define a type like this ==> abstract class Color case class Black() extends Color case class White() extends Color case class Gray(shade: Int) extends Color case class RGB(r: Int, g: Int, b: Int) extends Color <== This declares an abstract base type, and four specific derived types. These are types, not instances, like an enum. Each case class automatically gets some functionality:
    o Each class has a factory method with the name of the class to construct an instance. ==> scala> val b = Black() b: Black = Black() scala> val c: Color = Black() c: Color = Black() scala> val g = Gray(25) g: Gray = Gray(25) <== o All arguments in the parameter list are maintained as ``val'' fields. ==> scala> val g = Gray(25) g: Gray = Gray(25) scala> g.shade res0: Int = 25 scala> g.shade = 32 <console>:9: error: reassignment to val g.shade = 32 <== o You get deep recursive implementations of ``equals'', ``hashcode'', and ``toString'' ==> scala> g res1: Gray = Gray(25) scala> g == new Gray(25) res2: Boolean = true <==
In combination, this gives great power to a match expression, which we here put into a function that returns a String. ==> def describe(c: Color) = c match { case Gray(25) => "favorite color" case Gray(s) if s>255 => throw new IllegalArgumentException case Gray(s) => "shade of "+s case rgb @ RGB(0,_,_) => "No red in "+rgb case other => "Something else: "+other } <== This is better than a overloaded function, because you can make cases for specific values of arguments. ==> scala> describe (Gray(25)) res5: java.lang.String = favorite color scala> describe(Gray(16)) res6: java.lang.String = shade of 16 scala> describe (RGB(0,1,1)) res7: java.lang.String = No red in RGB(0,1,1) scala> describe (RGB(1,1,1)) res8: java.lang.String = Something else: RGB(1,1,1) scala> describe (Black()) res9: java.lang.String = Something else: Black() scala> describe (Gray(256)) java.lang.IllegalArgumentException ... <== You can leave off the ``match'' because a case expression is a function literal: ==> val describe: Color => String = { case Gray(25) => "favorite color" case Gray(s) if s>255 => throw new IllegalArgumentException case Gray(s) => "shade of "+s case rgb @ RGB(0,_,_) => "No red in "+rgb case other => "Something else: "+other } <== ``Option[A]'' and ``List[A]'' are parametric versions of case classes. In this way you can create nested cases. ==> scala> val test = Option(Gray(25)) test: Option[Gray] = Some(Gray(25)) scala> val list = List(Some(Gray(25)), None, Some(Gray(1))) list: List[Option[Gray]] = List(Some(Gray(25)), None, Some(Gray(1))) <== Since the outer ``List'' is a sequence, we can iterate over it with pattern matching: ==> scala> for (Some(c) <- list) {println(c)} Gray(25) Gray(1) <== This is actually equivalent to ==> list filter { case Some(c) => true case _ => false } foreach { case Some(c) => println(c) } <== Or better, iterate with our describe function: ==> scala> for (Some(c) <- list) yield describe(c) res6: List[String] = List(favorite color, shade of 1) <== Which is equivalent to ==> list filter { case Some(c) => true case _ => false } map { case Some(c) => describe(c) } <== Even better, let's do it the recursive way. ==> def print(list: List[Option[Color]]): Unit = list match { case Some(c) :: rest => println (describe(c)) ; print(rest) case None :: rest => print(rest) case Nil => () } <== This works because ``::'' (pronounced "cons") and ``Nil'' are the two case classes for a List. ==> scala> print (list) favorite color shade of 1 <== Here's the shorter version using a function literal: ==> val print: List[Option[Color]] => Unit = { case Some(c) :: rest => println (describe(c)) ; print(rest) case None :: rest => print(rest) case Nil => () } <==