Why I Choose Scala

Posted on April 11, 2017 · 8 min read

Disclaimer

As the title itself reflects, this is a highly opinionated post.

TL;DR

Why I choose Scala then?

  • Type-safe (statically typed + type inference)
  • High development productivity
  • Supports both Object Oriented and Functional Programming paradigms
  • JVM Language + Seamless Java interoperability

Background

The lead designer of Scala, Martin Odersky, has been involved in Java since 1995 and contributed to the current Java Compiler and Generics introduced in version 1.5.

Around 2001, at the École Polytechnique Fédérale de Lausanne (EPFL), he started to investigate the next challenges in software programming and he thought that unifying OO & FP would address those challenges.

The outcome was Scala (acronym for Scalable Language), in 2003. In 2011 he and other collaborators founded Typesafe Inc. (Lightbend as of Feb. 2016), a company to support and promote Scala.

Type safety

Dynamically typed languages have their place as well, they are versatile and have plenty of use cases where they shine. And of course, that's not only the case for Javascript (see Ruby, Python or Groovy, just to name some of them).

When talking about building an enterprise application though, type-safety is a must to me. That piece of software will be used to encode and manage business rules, and it'll be developed and maintained by many developers during its life which, in this context, should be rather a long time.

JVM

Coming from the Java ecosystem, transitioning to Scala is easier. It runs on the JVM so all you know about it prevails (memory management, configuration, fine tuning, etc). You can integrate Java libraries, frameworks and tools in a Scala application. Moreover, Java and Scala classes can be freely mixed.

The Scala community is an important part of the Java ecosystem.

OOP + FP

Functional Programming is on the rise nowadays. Beyond the hype, FP principles make it easier to reduce the complexity of a system by setting a clear separation between functions (pure functions) and side effects.

As Moseley and Marks described in Out of the Tar Pit:

Complexity is the root cause of the vast majority of problems with software today...

... it is our belief that the single biggest remaining cause of complexity in most contemporary large systems is state, and the more we can do to limit and manage state, the better.

The deterministic nature of pure functions along with the type system significantly reduce the cognitive load required to reason about them. The lack of nulls, thrown exceptions and mutability (accidental complexity) lets you focus on the important logic of the application (essential complexity).

Unlike many other FP languages, Scala allows a gradual, easy migration to a more FP style. You can start to use it as Java without semicolons and evolve it over time.

Development productivity

Besides the benefits of FP, Scala's features can boost development productivity even if used in a OOP fashion.

Immutability by default

Immutable objects and methods without side-effects make concurrent programming easier & thread-safe.

As Joshua Bloch stated in his book Effective Java:

Classes should be immutable unless there's a very good reason to make them mutable

In Scala, immutable is the default.

Every operation is a method, even ==

In contrast to Java, in Scala == is not a built-in operator but a method that can be overridden. For example, String class overrides it to compare the content of the strings.

Tuples

A tuple is an immutable sequence of values of multiple types.

https://gist.github.com/pbassiner/41c94ce57a3fd5da3a921587062ca2cb#file-tuples-scala

Option

A null value is often abused to represent an absent optional value. This means the null value is bubbling up the hierarchy call. Sometimes this just leads to an exception much higher in the hierarchy, where some piece of code isn't that null-friendly.

In Scala there's the Option type, and it represents values that might or might not be present. Instances of Option are either an instance of Some or None.

https://gist.github.com/pbassiner/41c94ce57a3fd5da3a921587062ca2cb#file-option-scala

Case classes

In Java, defining an immutable (for fairness in the comparison) POJO requires explicit declaration of the type members, constructor, getters and overriding the hashCode, equals and toString methods.

https://gist.github.com/pbassiner/41c94ce57a3fd5da3a921587062ca2cb#file-pojo-java

In Scala you get all that just by defining a class as a case class:

https://gist.github.com/pbassiner/41c94ce57a3fd5da3a921587062ca2cb#file-caseclass-scala

A case class is a regular class with reduced boilerplate by the compiler:

  • The constructor parameters become public fields
  • Methods toString, equals and hashCode are defined based on the constructor fields
  • A companion object (where you define the equivalent of static methods in Java) containing:
    • An apply constructor based on the class constructor
    • An extractor based on constructor fields

The methods in the companion object allow to perform pattern matching on instances of the case class (see next section).

Pattern matching

Scala has a built-in general pattern matching mechanism. It allows to match on any sort of data with a first-match policy:

https://gist.github.com/pbassiner/41c94ce57a3fd5da3a921587062ca2cb#file-patternmatching-scala

As you can see it can match values as well as data structures. This is of great use when in combination with case classes. With a small amount of code we can define an expression writer:

https://gist.github.com/pbassiner/41c94ce57a3fd5da3a921587062ca2cb#file-patternmatchingcaseclasses-scala

Another useful scenario is pattern matching Option:

https://gist.github.com/pbassiner/41c94ce57a3fd5da3a921587062ca2cb#file-patternmatchingoption-scala

Collections API

The Scala collections API provides plenty of methods to simplify manipulating data:

https://gist.github.com/pbassiner/41c94ce57a3fd5da3a921587062ca2cb#file-collections-scala

First-class functions

A function in Scala is a first-class value. Like any other value, it may be passed as a parameter or returned as a result. Functions which take other functions as parameters or return them as results are called higher-order functions.

https://gist.github.com/pbassiner/41c94ce57a3fd5da3a921587062ca2cb#file-firstclassfunctions-scala

Traits and composition

Traits are like Java interfaces but they can be partially implemented. This enables multiple inheritance (a mixin):

https://gist.github.com/pbassiner/41c94ce57a3fd5da3a921587062ca2cb#file-traits-scala

(Example taken from the official Scala Documentation)

Futures

Scala's Future[T] provides asynchronous, non-blocking computations that will eventually result in a value of type T. The future will either succeed or fail:

https://gist.github.com/pbassiner/41c94ce57a3fd5da3a921587062ca2cb#file-futures-scala

More than just vanilla Scala

The Scala community is increasing and it's more active every day, with many well known companies using it (LinkedIn, Twitter, Foursquare, Netflix, Tumblr, Soundcloud, Coursera, ...).

Lightbend (formerly Typesafe) is the most influential actor in the community. They are actively contributing to the Scala programming language and some frameworks on top of it. Their reactive platform is consists of the following components:

  • Lagom: a microservice framework
  • Play: a high velocity web framework
  • Akka: a toolkit and runtime for building highly concurrent, distributed, and resilient message-driven applications on the JVM
  • Spark: Apache Spark is a fast and general engine for large-scale data processing

Typelevel is another company which provides pure functional programming libraries for Scala. The more relevant ones are:

  • Cats: Lightweight, modular, and extensible library for functional programming
  • Shapeless: Generic programming for Scala
  • Monocle: Optics library for Scala
  • Circe: A JSON library for Scala powered by Cats
  • Doobie: a pure functional JDBC layer for Scala

Special mention: Akka

Akka deserves a dedicated section on its own merits. I am by no means an expert in Akka but I'd like to outline the most relevant features about it:

  • Meant for distributed systems, out-of-the-box clustering and location transparency
  • Based on the Actor Model, with supervision hierarchies, to provide fault-tolerance
  • Http - fully async and reactive HTTP server
  • Streams - back-pressured stream processing

I plan to write a post about it at some point but, in the meantime, refer to the Akka documentation for more information about it.

Conclusion

I find Scala a great choice, especially as a step forward for Java developers eager to embrace functional programming. It's not only about purity, category theory, functors, monads or higher-kinded types, these will be the logical consequences of shifting to the FP paradigm. In this context, Scala is flexible enough to accommodate developers in all stages of FP adoption.

On the other hand, for a Java company, moving to Scala it's an acceptable risk due to their compatibility and shared runtime. For this to succeed, it's important that at least one or two developers can take responsibility for its adoption, motivating, training and assisting the rest of the team, while periodically assessing the potential risks of generating knowledge silos.

Therefore, it's a win-win scenario: reasonable risk and happier developers.

Learning resources

If you want to learn more about Scala, these are some useful resources:

References


Comments

Would you like to leave a comment? Since this blog is hosted on GitHub Pages there's no straightforward way to do so.

Instead, you can add a comment in this GitHub issue. If you'd like to see it here, refresh this page after posting the comment.