Why Scala

tl;dr Scala has powerful language features that integrate nicely with the Java ecosystem.

At Tapad, we process a huge volume of requests per second with very low latency to serve well-targeted ads. As a young company, we have a small (but growing) engineering team that is responsible for keeping the ship running smoothly while simultaneously adding new features. So, performance and productivity matter a lot. Here are some of the things we like about Scala:

  • the JVM We understand the JVM and its quirks and characteristics, so staying in this known environment reduces risk from changing runtime and language to just changing the language. Some of Tapad’s codebase was Java and during the transition to 100% Scala, we were able to reuse our existing Java classes. Of course, the entire mature Java ecosystem is available to use as well.

  • hybrid FP and OO Scala is well known for combining functional programming with object oriented programming. In practice, we find this very pragmatic and intuitive.

  • type inference Reducing boilerplate makes code easier to read and write. Omitting the type signature variables and functions makes the code easier to scan. In more complicated blocks of code, it is useful to specify the type anyway to help understand the code and to leverage the compiler’s assistance when debugging a compilation error.


// Scala = terse

// type is inferred scala.collection.immutable.Map[java.lang.String,List[java.lang.String]]
val m = Map("a" -> List("apple", "apricot"), "b" -> List("banana"))
// Java = verbose

HashMap<String, List<String>> m = new HashMap<String, List<String>>();
m.put("a", Arrays.asList("apple", "apricot"));
m.put("b", Arrays.asList("banana"));
  • actors Our system is highly concurrent, and the Actor implementation from Akka makes it startlingly simple to write comprehensible code that leverages all the cores in our production machines. There are a variety of dispatchers that provide plenty of options to tune how the actors work, be it for a few actors bount to their own thread, or for millions of lightweight actors. Because actors guarantee that messages are processed sequentially, we can work with mutable state safely so long as it is hidden behind an actor.

  • named parameters/default parameters This makes it very simple to set up the default arguments to a method, and selectively override them from the invocation. This is commonly seen in Python; in Ruby the workaround is to pass parameters in a Hash.

  • traits and stackable traits This is effectively multiple inheritance, done right. Traits allow for common functionality to be implemented separately, and then mixed in to a class. This is like the ability to add implementing code to an interface. Traits can also be “stacked”, meaning that the trait can specify its own type (and therefore can only be included in specific types of clases); this provides the ability to chain behaviors together by calling super from the trait. The order of invokation depends on the order in which the related traits were mixed in. In addition to reducing cognative load, this makes orthogonal functionality very easy to test in isolation.

  • tuples These are simple, idiomatic, flexible data structures. They can be constructed without any ceremony: val myTuple = (1, "two"), or val (a, b) = (a, "two"). Access elements by index like thismyTuple._1, or match against them like this (1, 2) match { case (a,b) => println(a) }.

  • community It’s heartening to see the rapidly expanding team of talented engineers at Typesafe and the increased adoption of Scala in general. The attendance at the NY Scala Meetup has exploded from a handful of people a year ago to a consistent sellout crowd plus waitlist of close to 100.