7 Scala features we love

Simone Colucci
The Startup
Published in
8 min readOct 15, 2019

First time we approached Scala in xtream as software developers it was in search of a strongly-typed, coincise, compiled programming language to use for building a large Spark-based application. And I guess that’s not one rare case: to become initiated to the Scala features while learning Spark.

What we found however, was so much more than expected that we started falling in love with its traits (pun intended), its phylosophy and, as any true love requires, its downsides as well.

In this article I want to share our top list of features that we find particularly amazing in the language. Some of them will be simple, some complicated, most will be found in other languages as well. But the coexistence of all these and others in one place is what makes us enjoy so much the time writing our code in Scala.

Function Literals

Truth be told, the first time I saw idioms like the this on a Scala tutorial I thought it was some kind of black magic. What the hell is that _ ?
Nevertheless, I doubt anyone with a little of programming experience would question what the execution logic is. How the _ % 2 == 0 compiles and how can the filter accept that are a mystery, but the intent is readable and straightforward. No boiler plate, nothing but a pure intent.

Every programmer at his first days in Scala

Fact is, function literals are a cornerstone of how Scala delivers highly reusable components by the means of higher order functions. The clarity in that is similar to what a lambda function looks like in Python. Python-level conciseness and type-safety on the function to call are the reason why this feature makes an entry in our list.

For sake of clarity, not any valid literal syntax looks that magic:

Trait Mixins

In object oriented programming an interface is an abstract type that declares the general contract of some members, usually methods, which concrete implementations of that interface must fully-define.

Scala does not provide an interface keyword, but rather a trait one. And that is not just an eclectic naming choice, but a reflection of a precise intent: the Cambridge dictionary defines the word as

a particular characteristic that can produce a particular type of behaviour

Nowhere in the definition anything mentions the characteristic to be abstract or undefined. Indeed, Scala traits not only allow for the declaration of methods, but also for a concrete implementation to be defined. That may look like similar to what an abstract class is in Java, but here’s where we get to the fun part: a class can extend multiple traits at the same time. More precisely, we should say that multiple traits can be mixed in a class.

Below is an example which I partially revisited from real-code in one of our projects:

The NymexTrades class takes some of its MarketDataComponent traits from both the mixins, InternalFeed and InferredName. The only thing that’s left to implement is a concrete definition of the internal method. Good to go.

To us, that’s one way in which Scala helps the design of very small interfaces. Each one can focus on a specific behaviour, partially implementing a general interface (like the example above), or even providing generic functionality to be mixed in any kind of other type.

This is an example of a trait that provides a simple and closed functionality to be plugged in a class:

The Loggable trait is totally independent from the other mixins and can be used in a large variety of situations. It provides a pluggable functionality, and that’s what we find amazig about it.

Lazy evaluation

If you look close enough in the previous example, you’ll see that we have a strange syntax over there: what is going on with the message: => String parameter that’s accepted by debug method? Let’s talk about laziness.

Scala accounts for lazy evaluations to be part of your programs in two ways:

  • by providing a lazy keyword that can be applied to vals so that their expression is not evaluated until the very moment is necessary, if ever
  • by enabling functions to accept by-name parameters, to highlight the fact that the argument is not evaluated at the point of function application, but instead is evaluated at each use within the function.

In the Loggable trait we defined above, the message in debug is passed as by-name parameter, so that we know its computation will only be evaluated if needed, which is when the debug level of the class logger is activated.

We have to admit, if we try to do the same on Java, that’s not nearly as elegant.

Type Inference

In my experience, for any passionate Python developer going back to a strongly typed language can be annoying.

I know what I’m doing, would you let me write code already?

On the other hand, when building large applications types are a lifeline: they provide compile-time checks on the formal correctness of the program, documentation for the public APIs and a guidance for writing code on them.

Scala strives at picking the best of the two worlds by handling on the back all of the precious effort of checking your program when compiling, while at the same time reducing at the minimum possible the boilerplace on the code.

Type signatures have to be specified, but only to let the compiler know once what to expect. From that point on, it can infer by itself the rest, alleviating spoiled coders like us from typing redundant stuff.

Have a look here:

As a matter of fact, this simple feature helps us be happier and quicker while coding, and our functions and classes be shorter, more coincise and more readable at the same time.

Immutability fostering

We know we love you, strange elephanguin

Scala provides a unique fusion of OOP idioms and FP paradigms. On one hand, it provides everything is needed to comply with classic OOP-oriented programming: imperative methods, classes for state encapsulation, polimorphysm, inheritance. On the other hand, it enables all of the pure FP construncts to be pure in a functional meaning: function composition, higher-order-kinds, tail-recursion, …

Above all, however, we found amazing how this mixture helped us in leaning, without even noticing, to data immutability. The fact that everything is immutable is a key concept in pure FP and it may easily be its first and more appreciated benefit.

When data is immutable, your program becomes referentially transparent, which means that if you have somewhere x = f(y) you can apply that substitution everytime you have a reference of x, just like you would do in a mathematical equation. Math does not have mutable variables, and as lambda calculus (from which FP originated) is a formal system in mathemathics, FP made immutability one of its crucial points. But I’m digressing…

Scala does not enforce you to comply with immutability: however, it makes it natural and on the contrary kind of unappealing to do the opposite. Indeed:

  • It explicitely distinguishes mutable and immutable variables with two different keyword for creating them: val and var
    Surprisingly, that makes you realize you can get rid of var in most cases with little or no effort.
  • It provides automatic imports for immutable collections only. Do you want to use a List that you can mutate elements on? Go ahead, but oops you can’t. You have to explicitely import the mutable.List version.
    Try and not feel a little bit guilty then.

This is not a comprehensive list of how Scala helps writing programs as a sequence of pure functions called on immutable values. However, those aspects can be appreciated by any beginner and had a tremendous impact in our style of coding from day one.

Extensions Methods

The reasons behind Scala’s name are to be found in Martin Odersky’s words:

The name Scala stands for “scalable language.” The language is so named because it was designed to grow with the demands of its users

One of the features that make a language scalable (in the sense above), is the ability to be general enough to address any problem scenario, while at the same time accepting to be tailored on the needs, vocabulary and processes of the target domain of each application.

Extension methods are a way of achieving that. You take a class, either defined in your code or imported from a library, and you pimp it with attributes and methods that it didn’t have, but which clients will be able to use if they import your extension. Cool, isn’t it?

Here’s an example:

The powerful bit in here is that we can enrich base types, closed-library types and even our own highly reusable types with methods and attributes that are well-suited for a subset of use cases, and that can help us create our own version of the language tailored on our vocabulary. But that’s just the beginning…

Infix Notation

We think one of the top things that make Scala great it’s its coherent design principles: though being a complex and highly-customizable language, as we saw, it’s grammar size is way smaller than Java or C# ones. Sometimes it almost feels like a mathematical demonstration, where from few but very intense hypothesis (design principles) descend multiple and complex consequences (language features).

Back to our list, operators are an example of this coherence. They, simply put, do not exist as a reserved functionality in the language, but are just regular functions on an object instance. But how can a familiar expression like the proverbial 2 + 2 be just a matter of a function application?

Thing is in Scala functions can be infix between the instance on which they’re called and the parameters. In other words, given a: A , b: B and a function def f(b: B) defined on A you can write a.f(b) by infixing the operator, to get a f b. The + in the expression above is nothing more than a function with a symbolic name, defined on instances of the Int class and applied on another Int value.

Does it work only with symbolic functions? You can gess the answer. Check out more on infix notation in Scala in the official docs.

Thanks for reaching to the bottom of this list. If you had experience already with the language, we’d like to know if you agree with our top 7 or what would be yours instead. If you knew nothing about Scala, we really hope to have given you enough reasons to check it out immediately.

Ah, and don’t forget also checking out other articles from xtream on our Linkedin official page. Bye!

--

--

Simone Colucci
The Startup

Passionate software developer and co-founder of xtream. Functional programming enthustiast