bryanlcampbell.com

Learning Scala

If you happen to develop in Java, you should really look at Scala if you haven't already.  As you may know, Scala compiles into java bytecode with a JVM and works almost seemlessly with Java and vice-versa.  Like any language there are strengths and weaknesses (sometimes depending on the coder).  I will demonstrate a few cool features.

View bounds

View bounds is a new feature in Scala that lets you view one class type as a diffferent one.  Type A doesn't have to be equal to type B, you can fake it with a simple conversion.  This is great when you want to read the contents of an object dressed as another.  Furthermore, if you define this function to be implicit then this conversion is done automatically.
Here is a silly example of representing a list as an integer by using its length:

scala> implicit def listToInt(x: List[_]) = x.length * 2 / 3
listToInt: (x: List[_])Int

scala> val ratio: Int = List("hello", "hi", "hey")
ratio: Int = 2

scala> math.max(List(1, 2, 3, 4, 5, 6), 4)
res1: Int = 4

 Above there is a function called listToInt that takes any type of List as a parameter and returns a Int.  This function was defined to be implicit, which allows for any List automatically can be treated as an Int which you can see in the next couple of statements.

Behavior-Driven-Development

BDD is done differently here than I've seen it done before, but I thought this was a cool way to do it.

import org.specs._

object ArithmeticSpec extends Specification {
  "Arithmetic" should {
    "add two numbers" in {
      1 + 1 mustEqual 2
    }
    "add three numbers" in {
      1 + 1 + 1 mustEqual 3
    }
  }
}

 Test output is easy to scan for issues and behavior requirements

[info] Compiling 1 Scala source to /Projects/eclipse_workspace/sample/target/scala-2.10/test-classes...
[info] + Arithmetic should
[info]   + add two numbers
[info]   + add three numbers
[info] Passed: Total 2, Failed 0, Errors 0, Passed 2

Pattern Matching

There are many unique applications for pattern matching in Scala, and here is one example.

scala> val myList = List(1,2,3,4,5,6,7,8,9,10)
myList: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> myList.filter {
      |     case i: Int => i % 2 == 1   // odd number will return false
      |     case _ => false             // anything else will return false
      | 
}
res14: List[Int] = List(1, 3, 5, 7, 9)

 In Scala, the filter function on a List passes in a value and gets a boolean, then returns a new list on all values that passed as true.  Here you will find a commonly used pattern matching syntax to define the filtering.  Any value that is an Int in the List is defined by the first case, while all other value types are defined by the second.  What I like about the pattern matching in Scala is that it doesn't just check the value of a variable, you can also check the type (case i: Int => or case (x:Int, y:Int) =>).

Threads / Concurrency

Code lines are natually written sequentially, however, most of the time execution of these code lines doesn't have to be done sequentially.  Of course, most languages allow you to create threads so that some logic is ran concurrently.  There are usually 3 problems any coder faces:

  • Code is designed execution style (Callables, Runnables, Thread Executors, etc...)
  • Logic blocks enough to be worth the effort for performance gains
  • Thread Safety

Even though there are many cases to write code that is executed concurrently, due to the above traits, it isn't done as often as it should.   Scala has cut down on some of these requirements with a way to make asynchronous code easier and a more natural part of the the language itself

import scala.concurrent._
import ExecutionContext.Implicits.global

val f: Future[List[String]] = future { session.getRecentPosts } f onComplete { case Success(posts) => for (post <- posts) println(post) case Failure(t) => println("An error has occured: " + t.getMessage) }

In the above code session.getRecentPosts is executed asynchronously in a different thread.  There is nothing special about session.getRecentPosts to make sure that it is runnable, callable, etc...  Session.getRecentPosts doesn't even return a future, it just returns a List of Friends.  Since it is wrapped in a future clause it is automatically wrapped in a Future. 

 

There are many other things I like about Scala from the new constructors, easy mutators/accessors, traits, object (singletons).  There are a few things you can do in Java that you can't do in Scala, but overall it is a fun language.

 




Comments

--> -->