Using Scala’s Future.apply efficiently

I recently browsed through the scala.concurrent.Future code and noticed that, in addition to Future.apply, there are three other constructors:

Future.successful – This creates a completed future.
Future.failed – This creates a completed future with a given exception.
Future.fromTry – This creates a completed future with either a successful result, or an exception.

The reason why these constructors are interesting, is because they create completed futures, whereas Future.apply starts an asynchronous computation to eventually complete the future.

Isn’t that the purpose of a future, though? In most cases, yes! I have, however, seen some cases where using some of the other constructors might be more efficient. Consider the following (non real-world) example:

case class User(name: String)

def retrieveUser(userName: String): Future[User] = {
  userName match {
    case "testUser" => Future(User("testUser"))
    case _ => Future(retrieveUserFromDB(userName))
  }
}

Clearly, if we have some constant value, it would be better to use the following instead:

case class User(name: String)

def retrieveUser(userName: String): Future[User] = {
  userName match { 
    case "testUser" => Future.successful(User("testUser")) 
    case _ => Future(retrieveUserFromDB(userName))
  } 
}

This will avoid the unnecessary asynchronous computation in the first case.

TL;DR: Use the 3 mentioned Future constructors when returning a Future that requires no asynchronous calculation.

Hello, world!

Hi there! My name is Pierre Marais. I’m a functional programmer working with cool technologies like Scala, Akka & Play.

The purpose of this blog is to share some of the new things I learn by reading coding books & blogs.