Map'em up!

No, it is not the Map implementation that we are going to talk about. Let me ask you a very simple question. I assume that you have written functions or methods or routines or whatever you call it. What do you think that it actually does? ...., 3...., 2...., 1.... TimeUp. Let me answer that for you.

A function or a method maps the thingy on the left to the thingy on the right. The thingy on the left is your function argument and the thingy on the right is the value that the function computed for you using the argument you supplied it.

myFunction(leftThingy) = {
...
val rightThingy = doSomething()
...
rightThingy
}

So effectively speaking, a function maps one thing to the other. That's all to it. Now what relevance has this got to do with Scala? In Scala, map is a higher order function that applies a function to each of the parameter that you pass to it and returns the resutls. A piece of code snippet is a lot better I suppose.

Let's say you have a List of Int's and you now want to calculate the square of each element in the List and return the result as a List. Let's start with defining a square function that takes an Int and returns the square of that Int. Effectively, you are mapping an Int value to the square of it which again is an Int value. Your square function maps an Int to an Int (Int => Int in Scala syntax)

def square(x: Int): Int = x * x
...
...
val myList = List(1,2,3,4)
val mySquareList = myList.map(square)
...
...
println(mySquareList) //would print List(1, 4, 9, 16)
...
...

What happened was, you mapped a set of inputs to a set of output by applying a function to each of the input values. Did you get that? If not, I'm stupid and you are brilliant.

What the heck are Scala's ExecutionContext's?

An ExecutionContext or otherwise called a thread pool is vital when running asynchronous code. In Scala, there is a global ExecutionContext that you can supply to your asynchronous code blocks. An ExecutionContext is just an Executor of a Task. It executes a Task in such a way that it is free to execute the Task in a new Thread of its choice.

The Scala's global ExecutionContext uses a ForkJoinPool. The ForkJoinPool is an ExecutorService that executes a Task. Understandiny and demystifying the ForkJoinPool is out of scope for this blog, but I will just highlight what it does to your asynchronous code block:

2. Unlike other ExecutorService, the ForkJoinPool keeps an explicit association between tasks

So, the bare minimum that you have to know about the ForkJoinPool is that it is able to run small computations with little thread overhead!

Now when you wrap a piece of code in a Future block in Scala, there should be somebody, some thread to run that bit of code that is contained in your Future block. So from where does this thread come from? This is exactly where the global ExecutionContext from Scala pitches in.

There is yet another concept that is worth knowing about when using Future's and ExecutionContext's in Scala. Say you have a very slow computation that might cost you a lot of Thread time, how could you indicate this message about the upcoming slow computation to the run time so that this slow computation is given a special consideration and is made to run in such a way that you do not run out of threads when you have many of those slow computations waiting to happen. Enter the BlockingContext! Whack... yet another XXXContext!!!! Marking a piece of code in Scala in a BlockingContext is as simple as:

scala.concurrent.blocking { ... }
When you wrap your code in the blocking { ... } block, Scala places that block in a BlockingContext. What happens after that is better explained in the form of a dialogue that goes as: BlockingContext - Hey, Current Thread, do you have to do anything before I'm about to start this slow thingy? Current Thread - Oh... yeah, let me inform the ForkJoinPool about this ForkJoinPool - I will give a special new Thread to handle this slow thingy, I will also defer this BlockingContext to the managedBlock in my pool

You see, this is essentially one of the best practices that should be followed when dealing with slow running computations. Just remember to wrap them inside the blocking context!

So effectively Scala's Future's and its global ExecutionContext empowers you to write parallely executing code, keeps your CPU machinery in steam without going Thread-frenzy.

Partial functions in Scala

Before taking a look at what partial functions in Scala is, let's look at some examples that map an assorted List of elements:

val assorted = List(1,2,"joe","san")
assorted map { case i: Int => i + 1 }
The code above when tried results in a match error. The reason being that we have an anonymous function inside the map block that checks against each element and since the match is not exhaustive, it explodes with an error. Let's try the same example with the collect method available in the Scala collection library
val assorted = List(1,2,"joe","san")
assorted collect { case i: Int => i + 1 } // gives List(2,3)
Why did map fail while collect did what we wanted? If you look at the method signatures from the Scala API, it is pretty obvious that collect takes in something called as a partial function, which becomes the topic of this article. Here is my explanation and understanding of what a partial function is: A partial function is any function that is defined for a subset of its input domains. Let's take a small example to understand this:
def add(i: Int) = i + i
The input domain to this simple add function is the set of all integers. The add function holds good for the set of all integers, i.e., across the whole integer domain. You pass it any input int value, you will get a result which is also an int in this case. Let's take another case, but remember the fact that the function should work for any input in that particular domain and produce us a result.
def divide(i: Int) = 1 / i
What happens if I call divide(0)? We should have got a result, but that did not happen. Instead we failed with an error or an exception. So how do I define this divide function in plain sentence? The divide function divides the input for a set of all partial input domains! Does that make sense? The divide function works only for a partial set of integer domain. Let's now fix the divide function to make it cope up with the failure (divide(0))... no no not with try catch!, but with Scala's built in support for defining partial functions! Our refactored divide function as a partial function can be written as below:
val divide = new PartialFunction[Int, Int] {
def apply(x: Int) = 1 / x
def isDefinedAt(x: Int) = x != 0
}
We have now made the divide function to be a partial function. We can now check if the divide function operates for any of the input domain and decide if we call the function or not. The following example illustrate this:
divide.isDefinedAt(0) // tells us that it is not supported by returning false!
Let's now rewrite the same example but this time with a case block! This is just a Scala shorthand way to define a partial function.
val divide: PartialFunction[Int, Int] = {
case i: Int if i != 0 => 1 / i
}
Where did our apply and isDefinedAt go with our re-written partial function example? If you are just curios, try compiling your code and have a look at how this is expanded upon compilation. I'll leave that to you! If you are a bit lazy to look into the compiled code, have a look at this post here The Scala's partial function trait has the following signature:
trait PartialFunction[-A, +B] extends (A) ⇒ B
The definition as per Scala docs, a partial function is any function where the domain does not necessarily include all values of type A. Anybody who implements the partial function trait has to provide implementations for the apply and the isDefinedAt abstract functions which takes the type A and defines if that instance of type A belongs to the domain covered by the partial function. So that wraps our discussion on partial functions in Scala!

Making a Case for Scala Case classes

If you are like me that is fed-up with writing or generating those getters / setters in your domain objects or Data Transfer Objects or Value Objects, defering the process of writing at compile time is definitely a boon. Scala's case classes does exactly that. Here are some of the noteworthy things to know about Scala case classes.

1. They are defined with the keyword case and are always immutable in nature because the parameters are val's implicitly!

case class Person(name: String, age: Int)
Now you could of course make the parameters var's, but be warned that your equals and hashCode behavior that you implicitly get is not bound to do what you wanted it to do

2. The parameters that are passed to the case classes are treated as final and are instantiated in the class constructor

3. Simple to instantiate and you could also define some defaults to the parameters if you do not want to supply them each and every time

case class Person(name: String = "MyName", age: Int)

val person = Person(29) // Would instantiate a person with name = MyName and age = 29

4. Gives you implicitly defined equals and hashCode implementation

5. You can decompose them using Scala's pattern matching feature, the reason you can pattern match a case class is because you also get the unapply method implemented for all your case classes

6. The getter methods are generated by default for you and if you have any var's as parameters, a setter method is also generated for that parameter that is declared as a var. But please don't try to mutate in a case class!

With all that said, let's now do a simple pattern matching snippet using a case classes:

abstract class Animal(age: Int)
case class Dog(name: String, age: Int) extends Animal(age)
case class Elephant(name: String, age: Int, sex: String) extends Animal(age)

We have now defined two case classes each with it's own set of properties. Here is a sample of the different scenarios and the results when trying to pattern match:

def patternMatchAnimal(animal: Animal) = animal match {
case d: Dog => println("that was just Any Dog")
case d: Dog("MyDog", _) => println("that was indeed My Dog")
case e: Elephant(_, 100, _) => println("Wow! that elephant lived 100 years")
case _ => println("Were you a human! well not really")
}
...
...
patternMatchAnimal(Dog("AnyDog", 2)) // prints -> that was just Any Dog
patternMatchAnimal(Dog("MyDog", 2))  // prints -> that was indeed My Dog
patternMatchAnimal(Elephant("Ele", 100, "M")) // prints -> Wow! that elephant lived 100 years
patternMatchAnimal(Elephant("Ele", 101, "M")) // prints -> Were you a human! well not really
Having said that, there is much more to case classes. Have a look at any Scala text to read more on Scala case classes!

Scala for expressions - A deeper look

This article takes a deeper look into Scala's for comprehensions. The for comprehension / expression in Scala has the following syntax:

for ( seq ) yield expr
Indeed a very simple syntax underneath which lies a very strong fundamental concept. The seq in the syntax above could be a sequence of generators, definitions, and filters each seperated with a semicolon. Let us assume that we have to identify all the Persons from a List that matches a certain criteria. Ofcourse this is Scala and there are zillions of way to do this, but the focus of this article is to discuss about for erpressions. Let's now see how we can acheive this in just 2 lines of code.
val persons = List(person1, person2, person3)
for ( person <- persons; age = person.age; if(age > 18) ) yield person
// for (generator; definition; filter) yield value
Infact that was indeed a one liner. What we did was that we filtered for all persons that are 18 years or more old. Let's focus on each one of those sequences. Let's begin with the generator. The generator syntax pat <- expr, where expr typically returns a type that can be iterated over. In simple terms, a generator is anything or rather any type that has a method map, flatMap and a filter. Let us verify this ourselves with the help of the following code:
val myInt = 10
for ( i <- myInt; if(i > 10) ) yield i
error: value filter is not a member of Int
for ( i <- myInt; if(i > 10)) yield i
^
The code above fails for obvious reasons that type Int does not contain a filter method defined and hence does not qualify to be as a generator. Let's now modify it slightly and see what happens:
val myIntList = List(1,2,3,4,5)
for ( i <- myIntList; if(i > 4) ) yield i // returns List(5)
The myIntList now qualifies as a generator as it satisfies the 3 conditions that we laid out earlier for a generator. Before going furthur, let me leave you with a slightly more complicated example. I will leave it to you so that you can figure that out by yourselves. If you have done nested for loops in Java, the answer should be pretty obvious.
val list1 = List(0,1,2,3,4)
val list2 = List(5,6,7,8,9)
for ( i <- list1; x <- list2; if(i >= 4) ) yield i // ??? What happens?
Revisiting our Person list example:
val persons = List(person1, person2, person3)
for {
person <- persons
age = person.age
if (age > 18)
} yield person
The generator iterates through the person list and for each person in the list, the age of that person is extracted into a local val age and the age is checked if it is greater than 18, if yes that peerson is added to the result of the for expression.

Annoyed with Tuple numbering?

Scala seems to be like a gold mine, the more you dig into, the more you get. While you deal with tuples, when you want to access the elements of a tuple, you have to use the default numbering given to you by the Scala compiler. Say for example., you have a tuple as defined below:

val myTuple = (31, "Joesan", "M")
println(myTuple._1) // To access the first element

What you could alternatively do is to decompose the tuple into its constituent elements as below:

val myTuple = (31, "Joesan", "M")
val (age, name, sex) = myTuple
println(age) // To access the age set in myTuple
println(name) // Did you get the idea...

I find this way of decomposing the tuple and accessing the elements from it using some meaningful names much more elegant than fiddling around with numbers which unfortunately does not say much on what you are reading.

Sealed traits for better pattern matching

You probably know the idea behind using case classes and pattern matching them. Sometimes you might want the help of the compiler to tell you if you have pattern matched correctly by covering all possible cases. You can now get this sort of compiler support by creating a superclass for the case classes and marking them as sealed.

sealed trait Person
case class Student(name: String) extends Person
case class Teacher(name: String) extends Person
case class Author(name: String) extends Person
case class Bertender(name: String) extends Person
...
...
def printAPerson(person: Person) = person match {
case p @@ Student(_) => println(p)
case p @@ Teacher(_) => println(p)
}
With the code above, the compiler would now tell us that the match is not exhaustive and would show us the following:
warning: match may not be exhaustive.
It would fail on the following inputs: Author(_), Bertender(_)
def printAPerson(person: Person) = person match {...}
Sealed traits or abstract classes is a guarantee for the compiler to know that all the classes that implement the sealed trait or sealed abstract class should be declared in the same file. This way, the compiler knows for sure that all the possible subclasses is in the same file and can therefore provide us with the warning message on our pattern match logic. Now it's time for you to go figure out the meaning of the following code snippet:
def printAPerson(person: Person) = (person: @@unchecked) match {
case p @@ Student(_) => println(p)
case p @@ Teacher(_) => println(p)
}

Doing Linear Interpolation in Scala

In mathematics, linear interpolation is understood as a method of curve fitting using linear polynomials. A polynomial is just an expression that consists of variables along with their co-efficients. An example of a polynomial would be:

x+2y²

In the above equation, the variable x has 1 as its co-efficient and the variable y has 2 as its co-efficient. Let us assume that we have a set of linear data points pointing to the x and y axis:

x = {2,5,7,10,11,15,17,19,21,25} y = {3,6,8,10,14,16,19,21,23,26}

Given a value x, we can find the value y. For example., for x = 2, the corresponding y is 3, for x = 11, the corresponding y is 14. Now we are interested in finding the value of x and y within our set of data points.

What is the value of y for x = 13 or what is the value of x for y = 13. Since the data points for both the x and y co-ordinates are linear, we can use the linear interpolation technique to find out the values for the desired data points. Geometrically, the linear interpolant is just a straight line between two known data points. Let us assume that our two data points are represented as (x0,y0) and (x1,y1). We are interested in finding the values of x and y that lies between these data points. Since we are in the linear boundary, geometrically speaking the ratio of the difference between x and y co-ordinates between two data points are equal.

Let us try to ascertain this with some numbers. Let our data points (x0,y0) be (2,3) and (x1,y1) be (5,6). The ratio y1/x1 should be equal to the ration y0/x0 and in our case, 6/5 == 3/2. Extending this idea, we can now say that the ratio of the difference between two data points should be geometrically equal between the two co-ordinates. If we are interested in a data point (x,y) which lies in-between (x0,y0) and (x1,y1), our formula now becomes:

y - y0 / x - x0 = y1 - y0 / x1 - x0 which when solving for y, we get the following equation:

y = y0 + (y1 - y0) * (x - x0) / (x1 - x0)
We now have the formula for linear interpolation, let's now implement that in Scala. Let us represent our data points as a Scala List:
val x = List(2,5,7,10,11,15,17,19,21,25)
val y = List(3,6,8,10,14,16,19,21,23,26)
val zippedDataPoints = x zip y
We define a function that takes these two zipped List of data points and an additional parameter for x. The function uses the formula to find the value of y for a given x. Here is the function:
def interpolate(givenX: Int, dataPoints: List[(Int, Int)]) = {
// edge cases
val (lastX, lastY) = dataPoints.last
givenX match {
case a if givenX >= lastX => lastY
case c => {
val (lower,upper) = dataPoints.span { case (x,y) => x < givenX }
val (x0,y0) = lower.last