Considering Scala?

Thinking of using Scala in your next project? This article will help you decide if Scala is right for you and your team.

Choosing a language isn’t all about features and trendy new programming paradigms; tooling, libraries and recruitment are also important. this article looks at Scala in the round.

Scala isn’t exactly the new kid on the block anymore. It was first released in 2004 to a fair amount of buzz and excitement — some even called it a better Java, a title I’ve always been skeptical of.

Since then it’s matured into a very powerful and flexible language, relied upon by some very large and impressive organisations. So lets see what Scala has to offer now and whether it's a good choice for your next project.

Tooling

I’ve been using Scala for over 8 years now and I must say that in the beginning Scala’s tooling was pretty poor! However, it’s 2019 now and I’m pleased to report that a lot has changed.

IDEs and Editors

Nowadays Scala developers have a number of choices when it comes to IDEs and editors, but in my opinion one stands out head and shoulders above the rest.

JetBrains — probably best known for their Java IDE — have developed an absolutely superb Scala plugin for IntelliJ.

It is without doubt the most complete IDE experience for Scala that exists right now. The plugin is mature and stable with all the bells and whistles you’d expect from a fully fledged IDE: code completion, refactoring, hints, error highlighting, snippets, the works!

What’s more, you get all of this for free! The Scala plugin is available in the community edition of IntelliJ and appears as a featured plugin during install.

The folks at JetBrains have done a fantastic job and continue to actively develop the plugin, but be warned, whilst IntelliJ is undoubtedly a brilliant IDE it is definitely on the heavy side! Start up times can be pretty infuriating at times, and occasionally it doesn't feel very responsive especially if it's in the middle of indexing your code but I guess that’s the price you pay for having all those advanced features.

Personally, the "heavyness" of IntelliJ doesn't bother me that much, I like all the features it offers, and I'm willing to suffer the odd bit of sluggish performance, but I appreciate that other developers would be put off by this.

If you’re one of those types then fear not, the Scala community has been busy integrating with a host of code editors.

Metals is a language server with support for VSCode, Atom, Sublime, Vim and Emacs. It’s still very new and therefore not as refined as the Scala plugin for IntelliJ but it’s really very good.

It provides all the things you'd expect from a modern editor right out of the box: code completion, type highlighting, goto definition etc and new improvements are being released almost every month.

It’s a very impressive project and one that has opened up Scala to a host of very popular editors.

Other tools that deserve a mention — in many ways they were the real trailblazers for Scala — are Scala IDE, an Eclipse plugin that has been around for quite some time and Ensime, a language server similar to Metals. Both of these tools are mature and usable but looking at their github pages haven’t received much love in recent months.

Build Tools

You’re really spoiled for choice here. Scala is a JVM based language and as such has leveraged Java’s build systems.

Both Maven and Gradle support Scala by providing mature and stable plugins. If you come from the Java world you should feel right at home here.

Scala also makes use of Maven’s central repository, so all the dependencies are in the same place. As long as you know Gradle or Maven you shouldn’t need anything else to get started with Scala.

However, the Scala community wasn’t content with just two build tools, they wanted to create their very own. SBT — the Simple Build Tool — is a build tool developed in Scala making use of Scala’s advanced syntax rules to create a domain specific language for scripting build processes.

SBT is definitely one of the more popular build tools for Scala development but to be honest it doesn’t really provide anything you won’t find in Gradle or Maven.

Libraries and frameworks

This is where Scala really shines. Like other JVM based languages, Scala is bytecode compatible with Java. That means any Java based library or framework can be imported straight into your Scala project and used as if programming in Java.

This is a huge benefit! One that can’t really be stressed enough. Java has a gigantic ecosystem including frameworks and libraries for everything from web development to machine learning, and Scala gets it all for free!

That isn’t too say that the Scala community are a lazy bunch, freeloading off of Java’s success. Far from it!

Scala and Java are actually quite different languages and although you can use Java libraries directly in Scala projects it’s usually better to use a Scala based library instead. Scala based libraries are more likely to Scala’s syntax and language features.

For almost everything you can think of Scala will likely have a mature and high quality open source project to rival anything found in Java.

Below are just a tiny sample of them:

Play

Play is an MVC web application framework. It’s light weight, very fast, and completely stateless. It’s built on top of an actor framework giving it excellent support for asynchronous programming.

Akka

Akka is an actor framework used to make distributed applications. It’s this framework that Play sits on top of.

At the core of Akka is something called an “actor.” An object capable of sending and receiving simple messages to and from other actors.

Actors run independently from one another and can even run on different machines passing messages to each other in a manner which is completely transparent to the developer.

Using actors as a basic building block Akka has developed a full featured reactive streaming library called Akka streams, perfect for developing functional reactive applications.

Slick

Slick is a functional relational database mapper.

It basically turns a database into a pseudo collections library capable of filtering, mapping and zipping data from a database as though it were an in memory collection.

It’s a lot more complex than that of course but that gives you the basic idea.

Cats

Cats provides data structures and type-classes for hard core functional programming.

Scala leans heavily on functional programming concepts. The core language goes a long way to supporting this style of programming but there are a lot of things that should really be provided by third party libraries.

This is where Cats comes in. It provides a bedrock of type-classes and functions that enhance types found in the standard library which ease development of functional code.

There’s obviously many more libraries I could mention, more than I could possibly write about in a single blog article, but suffice it to say that Scala’s ecosystem is absolutely fantastic and one of the main reasons for choosing it for your next project.

Advanced Language Features

Scala has many advanced features that make it a compelling choice for a new project. But it can be a double edged sword.

Scala has a bit of a reputation for being a difficult language to learn, partly because of the number of new concepts introduced to the programmer, and partly due to the flexibility of the language which offers multiple ways of achieving the same goal.

But in my experience investing in Scala pays dividends. The learning curve is steep but once you’re over it you have access to an incredibly powerful, expressive and productive language.

Scala’s ability for abstraction is second to none and the tools it provides facilitate many different ways of modeling problems which suit a large number of domains.

Lets take a look at some examples:

Type-classes

Type-classes are actually a feature from Haskell that Scala adopted by using a very powerful language feature known as implicits.

The problems associated with developing deep class hierarchies in Object Oriented languages are very well documented so I won’t rehearse them here.

Type-classes are an alternative way of structuring code which alleviate some of the problems that arise from deep class hierarchies in Object Oriented Programming.

The posh technical term is “Ad-Hoc Polymorphism”, but its easier to think about type-classes as sets of associated functionality which you can add existing types to by providing a function which adds the target type to the set.

You can then write code in terms of the Type-class, which can take any type as a parameter as long as there is some “evidence” of that type being a member of the Type-class.

Lets take a look at a simple example:

trait Json[A] {
  def toJson(a: A): String
}

case class Person(name: String, age: Int)

object Person {
  implicit val personToJson = new Json[Person] {
    def toJson(person: Person) = 
      s"{'name': '${person.name}', 'age': ${person.age}}"
  }
}

def toJson[A](a: A)(implicit ev: Json[A]) = ev.toJson(a)

Here we have a simple Type-class called Json which defines a single function for converting some type A to a Json string. We then define a type Person which we add to the Type-class using an implicit function. Finally there's a generic function called toJson which operates on any member of the Json Type-class.

This code looks similar to a Java interface but the really useful thing here is that it’s possible to add any type to the Type-class regardless of whether you authored that code or not by providing a simple function.

Basically types can be retroactively added to Type-classes. It’s also possible to define different implementations of a Type-class for the same type and inject the correct one using an implicit.

Functional Programming

Functional programming is a huge and complex topic, I couldn’t possibly do it justice in a single blog article.

Instead I’ll just show you a common functional technique used in Scala to abstract over asynchronous computations.

Fetching data from some webservice and using that data to call out to another webservice is a fairly common task nowadays.

Monads are a functional technique for composing functions together whilst abstracting away some complexity. Futures are a Monad that Scala provides in it's standard library for abstracting the asynchronous nature of function calls. They hide away the details of threading and error handling, freeing up the developer to focus on what they really want to do.

def fetchProductsAsync(): Future[List[Product]] = ???
def fetchRevewsAsync(products: List[Product]): Future[List[Review]] = ???

for {
  products <- fetchProductsAsync()
  reviews <- fetchReviewsAsync(products)
} yield reviews

This code may look a little strange, after all why are we using a for loop to handle asynchronous function calls?

Well, Scala’s for loop is much more interesting than for loops in other languages. In fact, they’re not for loops at all, they’re called for comprehensions and they go hand-in-hand with Monad.

The first line in the for-comprehension in the code above calls a function which returns a Future. The Future handles all the threading for us by deferring to something called an execution context — a thread pool basically.

The for comprehension calls a special function defined on the Future called flatMap which takes a function that operates on the result of the Future and returns another Future.

In this case that function is the second line in the for comprehension where we’re using the result of the first call in the second asynchronous call.

We can keep chaining these async functions together without worrying if one of the calls fails. We get to focus on the case where everything goes according to plan.

Now, if one of the calls does fail then all subsequent calls will also fail and we can handle the failure after the for comprehension. This is because of the way flatMap is written for Futures. Notice how this code is very clean, there’s no waiting, polling, error handling or complex if statements. All the messy details are abstracted away by the Future Monad.

Recruitment and Training

Ok, enough about language features and libraries. After all, programming languages and libraries don't build products, developers do! What about building teams? How easy is Scala to recruit for and train?

Recruitment

Having access to a large pool of high quality developers is absolutely essential when developing a new product. You don’t want to get half-way though a project only to find you can’t expand because you can’t get the talent.

I can’t talk for the wider world, but in the UK at least, Scala has seen a fair amount of success in the tech industry having been adopted by some big players such as the BBC, the Guardian and Her Majesty’s Revenue & Customs (HMRC).

However, it’s not all sunshine a lollipops for Scala, it’s still a skill in short supply. It’s difficult to get exact figures but if you look at Stack Overflow’s Developer Survey you’ll find that only 4.2% of developers use Scala professionally, making it only the 20th most used technology.

In the UK — at the time of writing — according to ITJobsWatch there were 2,367 jobs citing Scala over the last 6 months, that’s approximately 1/10th the number citing Java!

There is demand for Scala but, unsurprisingly, it’s nowhere near the level of the Behemoth that is Java.

Training

So, Scala developers may be a little tricky to come across but what about training your existing team?

Ask any developer what they've heard about Scala and I bet there'll say "Scala is a difficult language to learn" and whilst that's not completely true, there is some truth in that.

I’ve run several training courses for companies, including the BBC, and I’ve found that most developers pick up the core of the language very quickly. Within a day they’re writing good Scala code — allbeit in a Java-esque fashion. The difficulty comes when learning how to structure and develop Funcational code.

Scala is easy, functional programming... less so.

When it comes to training courses and training material Scala does pretty well. There's a lot of material and documentation available but learning it takes time! However I can honestly say, from my own experience, that learning Scala doesn't just make developers good at Scala, it makes them better programmers in general because of all the new concepts they are exposed to.

So, should you use Scala?

Ultimately that’s up to you.

It can be a bit more challenging to build a Scala team because of the steep learning curve and the relative lack of experienced developers compared with mainstream languages. But once that team is assembled you’ll have access to a uniquely powerful, flexible and productive language with access to a huge and vibrant ecosystem.