Sunday, January 6, 2013

Scala function literals

Functions are an important part of the Scala language. Scala Functions can have a parameter list and can also have a return type. So the first confusing thing is what's the difference between a function and a method? Well the difference is a method is just a type of function that belongs to a class, a trait or a singleton object.
So what's cool about functions in scala? Well you can define functions inside functions (which are called local functions) and you can also have anonymous functions which can be passed to and returned from other functions. This post is about those anonymous functions which are referred to as function literals.
As stated, one of the cool things about function literals is that you can pass them to other functions. For example, consider snippet below where we pass a function to a filter function for a List.
List(1,2,3,4,5).filter((x: Int)=> x > 3)
In this case, the function literal is (x: Int)=> x > 3 This will output: resX: List[Int] = List(4, 5). => called "right arrow" means convert the thing on the left to the thing on the right. The function literal in this example is just one simple statement (that's what they usually are), but it is possible for function literals to have multiple statements in a traditional function body surrounded by {}. For example, we could say:
List(1,2,3,4,5).filter((x: Int)=>{
  println("x="+ x);
  x > 3;})
which gives:
x=1
x=2
x=3
x=4
x=5
resX: List[Int] = List(4, 5)
Now one of the key features of Scala is to be able to get more done with less code. So with that mindset, let's see how we can shorten our original function literal. Firstly, we can remove the parameter type.
List(1,2,3,4,5).filter((x)=> x > 3)
This technique is called target typing. The target use of the expression in this case, what is going to filter is allowed to determine the type of the x parameter. We can further reduce the strain on our fingers by removing the parentheses. This is because the parentheses were only there to show what was been referred to as Int in the parameter typing. But now the typing is inferred the brackets are superflous and can be removed.
List(1,2,3,4,5).filter(x => x > 3)
Shorten it even more? yeah sure... We can use the placeholder underscore syntax.
List(1,2,3,4,5).filter(_ > 3)
Underscores have different meanings in Scala depending on the context they are used. In this case, if you are old enough think back to the cheesey game show blankety blank.
This gameshow consisted of of sentences with blanks in them and the contestants had to make suggestions for what went into the blank. In this example, the filter function fills in the blanks with the values in the Lists it is being invoked on. So the filter function is the blankety blank contestant and the List (1,2,3,4,5) are what the filter function uses to fill the blank in.
So now our code is really neat and short. In Java to achieve the same, it would be:
Iterator<Integer> it = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5)).iterator();
while( it.hasNext() ) {
    Integer myInt = it.next();
    if(myInt > 3) it.remove();
}
So, here we can see where Scala make code shorted and development time quicker. Till the next time!


1 comment:

  1. Even if the java example does the same thing, it fails at the key aspect of returning the filtered list. Even more win to Scala.

    ReplyDelete