No clever puns with Future today…

Concurrency, what about it?

The common understanding about concurrency is that it is difficult. At least relative to purely sequential software. It is clear that a parallel algorithm must be at least as complex as its sequential counterpart. If you’ve ever tried using semaphores or mutex (what’s the plural of that??) for concurrency, for example in Java or C/C++, you know that it can indeed be very tricky. Now, if you finally achieve a working piece of software using semaphores, you would surely hate to prove that it is deadlock-free. So what does Scala do to improve on the situation?


Scala reinvents the notion of Actors. Instead of giving a thorough introduction to the concept, it can be described as an asynchronous message passing framework using pattern matching to handle events/messages. The framework is indeed a nice abstraction for concurrency, but it still requires you to create and start new actors which in the end resembles the typical way we create new threads to do concurrent tasks. In the end, this is somehow unsatisfactory for our everyday needs. I often need (want!) to do what i recently learned to be called embarrassingly parallelizable tasks, but as with mathematicians, the best computer scientist is a lazy one and thus I can’t be botherd with extending Actor everytime I need concurrency.

Futures for the lazy

Luckily Scala caters to the lazy computer scientists with the cheesily named Futures. The idea of futures is simple. Instantiate a future object with a zero-arity function ( or Body ) and alakazam, the function is executed in the background, hopefully on another thread. I guess it’s time for an example:

1
2
3
4
5
6
7
8
9
10
11
import scala.actors.Futures.future //it's a function
 
def fib(n:Int):Int = n match {//Something slow
    case 0 | 1 => 1
    case _ => fib(n-1) + fib(n-2)
}
 
val a = future { fib(44) }
val b = future { fib(45) }
 
println("a:"+a()+"\nb:"+b())

So the function fib is very slow, and since we can’t imagine a better implementation, we can at least put some of those extra cores to work. The fun starts at line 8-9 where we call the function future from the Futures object which takes a zero-arity function and returns the future representing that calculation. These futures start applying the function immediately. Once you decide to apply the futures though, two things can happen:

  1. The calculated value is returned
  2. The value is not ready yet, and the current thread blocks

In case 2, the thread is notified once the value is ready and in turn the application of the future returns it. In this example, depending on your setup, you can go grab a cup of coffee or sit and watch your cpu-monitor for dual-core action. Better yet, increment the numbers and do both :).
If this is in anyway confusing, the following should convince you.

How hard can it be?

An example implementation of futures can be made in very few lines. First a function similar to the future function on the Futures object is defined. As stated earlier, this simply returns a future which is created with the given function.

The Future class extends Actor and it starts itself right away. When an actor starts, the function act() is called. Now all that needs to be done is to compute the function and set the synchronized variable to the function value. All locking mechanisms are implemented with the SyncVar so we don’t even need to know anything about concurrency. The only magical thing going on in this class is the fact that Scala allows functions with the identifier apply() to be called using () like in the above example. This probably has something to do with what can be parsed, after all, def ()() = … would be a silly zero-arity function! Also, I am more than satisfied with the freedom of choice for identifiers in scala.

1
2
3
4
5
6
7
8
9
10
import scala.actors.Actor
import scala.concurrent.SyncVar
 
def future[T](body: =>T):Future[T] = Future[T]( ()=>body )
case class Future[T](f:()=>T) extends Actor {
	var v = new SyncVar[T]
	this.start()
	override def act(){ v.set(f()) }
	def apply():T = v.get
}

Before The Internet engulfs me in flames, this is of course a very simplistic implementation and the real Future class is somewhat more advanced. But this version is quite nice, don’t you think?

 

One Response to No clever puns with Future today…

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">