🌞


Note that this blog post has been archived. Information may be out of date or incorrect.

The bright future(s) of Scala programmers

The Scala library is pretty extensive, and I’ve only recently (about 4 months ago) started programming in Scala, so I really haven’t seen much of it yet. I was inspired to write a little something on the different Future-types available in Scala when I read this question on Stackoverflow, and while researching the topic I really learned a lot about Futures and the Scala library in general.

A sidenote on classes and objects

In Scala: a class in Scala behaves exactly as we would expect it to behave in Java. We can create as many instances as we want to, it has methods, a constructor (even though it is implicit) and it has member fields. The only thing “missing” in Scala classes are static methods. As you may or may not know, these are defined in objects, which are basically a singleton instance of a class which is created automatically for you on first access. The benefit of specifying using objects is a clean separation of your methods into those who operate on your instance and those who not. It also keeps the memory footprint of your instances as small as possible (as with Java static methods).

Now the real deal

If you search for Future in the Scala API, you get the following results (there are actually some more, which are not displayed because they are private classes/objects):

  • scala.actors
    • Class Future
    • Object Futures
  • scala.collection.parallel
    • Object FutureThreadPoolTasks
    • Trait FutureThreadPoolTasks
  • scala.concurrent
    • Trait FutureTaskRunner
  • scala.parallel
    • Future

scala.actors._

Lets start with those in the scala.actors package, as those are relatively well known. A little knowledge of Actors is required to understand the following section, so I’d recommend reading this short tutorial on Actors.

abstract class Future

First of all, lets see what the documentation says:

A function of arity 0, returing a value of type T that, when applied, blocks the current actor (Actor.self) until the future’s value is available.

And that is basically all there is. If you are communicating with an Actor from anywhere outside of another actor (which can receive asynchronous replies to messages simply with another message, using the sender reference) and you need the reply to a sent message, you have two choices:

  • Send a blocking message which waits until the Actor is done computing your result
  • Send a message using a method which returns a Future, and block on that Future only if you really need the value in question (which by then may have alreay been computed)

So a Future is a placeholer for a value which does not yet exist, but probably will in the near future. The following is also interesting:

A future can be queried to find out whether its value is already available without blocking [using “isSet”].

This allows you to do whatever you want until the value you need has been computed/fetched, and you can periodically check if the value has become available.

When digging a bit into the Scala library source code, I found out that Futures are actually just actors. Future itself is a an abstract class, which is extended by the private class FutureActor. This last class is the one that actually implements the Future-functionality.

object Futures

The object Futures is by far not as interesting, as it is merely a container for the “Methods that operate on futures”, the handy factory method future which asynchronously evaluates the passed block, returning a future representing the result. A small example would be this:

import scala.actors.Futures
val f = Futures.future {
    println("Start: inside block")
    val s = System.currentTimeMillis
    while(System.currentTimeMillis < (s + 1000)) {
        // Simulate computation
    }
    println("Start: end of block")
    42
}
println("After future")
println(f())
println("The end")

Which should result in something like

Start: inside block
After future
Start: end of block
42
The end

This demonstrates that the future-call does not block the following code until you actually try to retrieve the value of the future (note that the output is non-deterministic. After future could also appear at the beginning of the output).

scala.collection.parallel

This packages is new to Scala 2.9.x and implements parallel counterparts for some of our favorite collections. These all start with Par:

  • ParIterable
  • ParSeq
  • ParSet
  • ParMap

As you may have known or guessed already, these collections implement all possible operations in a parallel manner without you having to worry about it. A small demonstration:

(1 to 10).par.map { b => print(b + " "); b * b }
3 1 6 2 7 4 5 9 10 8
    # => (1, 4, 9, 16, 25, 36, 49, 64, 81, 100)

The result will always be the same, but the order in which the elements are processed is again non-deterministic. Also, if you are on a multicore system, you will probably experience a nice performance boost for larger collections.

trait FutureThreadPoolTasks

The FutureThreadPoolTasks trait extends the Tasks trait, so lets take a look at that one first. The comment above the trait says:

A trait that declares task execution capabilities used by parallel collections.

Judging from the other source comments and the methods found in the Tasks trait, a Task represents a unit of work which needs to be computed. Depending on wether or not a problem is divisible further and if there are more resources available, a Task can split up a Task further by creating more tasks.

Now the FutureThreadPoolTasks trait itself is just a way to compute tasks, which uses the java.util.concurrent.Future class for its synchronization, that is, it does not use scala.actors.Future! From the source:

An implementation of tasks objects based on the Java thread pooling API and synchronization using futures.

object FutureThreadPoolTasks

Once again not very spectacular, just a companion object containing a few (actually only three) utility methods which the FutureThreadPoolTasks trait uses.

scala.concurrent

The documentation on these classes is really bad and apparently there are very few if any (I didn’t find a single one) examples which demonstrate the usage of these classes. I will definitely try to gather more information on these and expand on this section as soon as I can!

scala.parallel

trait Future

This seems to be a “Work in progess”, as the scala.parallel package only contains this trait. From what I can tell, this is going to be related to a Future implementation which does not use Actors, but that is just a guess. The signature of the trait is the following

trait Future[@specialized +R] extends (() => R)

I am not even going to try to explain the @specialized annotation or variances (the + before the generic R type), but the basic idea in this trait is that a Future is a function which, when executed, returns the value (and must therefor block if it has not been computed yet).

Also, there are only two methods inside the trait itself, apply and isDone. My guess is that isDone, just like the scala.actors.Future.isSet, is supposed to be a non-blocking call to see if the value has been computed, and the apply method should be used to actually retrieve the value.

If anyone knows more on this topic, I’d love to hear about it.