Scala for Python developers

Antoine Doeraene
6 min readFeb 5, 2020

Introduction

If you are a Python developer, perhaps you ever felt the need to step up your Django application, or your data pipeline, to the next level, towards a technology which allows to build larger, safer and more robust softwares.

It turns out that Scala is an excellent fit to these issues. In particular for Python developers who, I’m sure, value the clear and intuitive syntax, the scripting-like feeling while coding, and the support for object oriented programming. Good news, you also have all of that in Scala, and so much more…

One thing that could refrain someone is the “where to start” impression that a new language can give. So let’s be reassuring and put in parallel the basics of Python and the basics of Scala. Also, the resistant legend that Scala is hard is certainly something that could push back a company to take the last leap. Well, as you will discover, you can learn in, say, two days basically everything that you were doing in Python (except of course manipulating the `__dict__` field of objects, but you should not do that).

In the following, we are going to explore some of the basics of Scala with a Python developer mindset, and see how some of the features of Python translate to Scala.

There are three important things to note before diving in:

  • As you might know, Scala is a statically typed, compiled language. I’m not stressing this fact in the following. This is because how matter how you put it, it is only when you actually practice the language that you feel how comforting and helping it is. After all, the compile phase can (also) be viewed as a first set of unit tests, that are automatic and mandatory.
  • This should not be taken as a “dictionary” between Python and the basics of Scala. In fact, a dictionary between two languages should never exist. You should rather read this with the mindset of “I’m doing this in Python, how would Scala developers achieve the same?” instead of “this class in Python translates to that class in Scala”.
  • you won’t find any instruction for setting you up. If you’re like me and you consume Medium articles while waiting at the dentist, or doing the line at your grocery store, then you most probably don’t have a computer to do it right now anyway. There are plenty of resources out there for helping you with that. Most of them will probably include installing sbt, IntelliJ, adding metals extension for VScode, or ammonite. If you’re fond of notebooks, perhaps Netflix’s Polynote could be a good fit, especially since it interoperates with Python.

Let’s get started.

Variables

In Python you declare variables simply by assigning them values, like `x = 3`. In Scala, you need to add the identifier `val` to write `val x = 3`. Notable difference, though, you can’t change the value of `x` afterwards. We don’t do that in Scala. (For the experts only, you can if you write `var` instead of `val`.)

Functions

Defining functions in Scala is very similar to Python’s way:

instead of one of

The four main differences are

  • in Scala, you are forced to write the types in argument. You are free to let the return type unspecified (inferred), but it’s generally considered bad practice
  • The `return` keyword is not necessary in Scala
  • The equal sign is used to start the body, instead of the colon (the colon is used to type the return type)
  • If you have a substantial function body, Scala uses curly braces instead of indentation

Working with lists

Creating lists and “dictionaries”

In Python, you typically use the square bracket syntax for lists, like `ls = [1, 2, 3]`. In Scala, you simply call the `List` “constructor” function, `val ls = List(1, 2, 3)`. Again, while in Python you can change your list `ls`, with, e.g., `ls[1] = 4`, you can’t do that in Scala (it’s actually never necessary).

For dictionaries, which are called `Map` in Scala, you simply use the `Map` constructor. For example,

d = {3: “hello”, “foo”: “bar”}

becomes

val d = Map(3 -> “hello”, “foo” -> “bar”)

(The arrow `->` might look like a special syntax, whereas actually it’s just a way to construct a pair `(a, b)`). Accessing an element in the map is done with parenthesis, instead of square brackets (`d(3)` instead of `d[3]`). Square brackets in Scala are reserved for “type parameters”. Note, however, that since Scala is statically typed, the map we defined is a map from `Any` (which literally means anything) to `String`. This is probably not a good idea as you “can’t” do anything with an Any in Scala.

Transforming the lists

In Python, there are typically two ways of manipulating lists (and dictionaries). Either with list comprehensions, or using built in functions `map`, `filter`… In Scala, you also have two choices: either by calling “transformation” methods on the lists (like map or filter), or using *for* comprehensions. So let’s see a hotchpotch of examples. We will consider `xs = [1, 2, 3]` (and equivalently `val xs = List(1, 2, 3)`).

Mapping

The following are essentially equivalent:

and

Filtering

You could do:

or

Groupby

The Scala collection has a `groupBy` method for grouping elements together, and creating a `Map`. To group elements by whether they are odd or even, we can do

The closest thing you can get in Python would be using the `groupby` function from the `itertools` module:

The list could go on for a long time, so be sure to check the standard API if you need to manipulate lists — there is likely all the things you need to do!

Handling “missing” elements

In Python, we can use `None` for assigning (or returning) missing elements. Since Python is interpreted, there are no real gain to have something more robust: nothing will prevent you from writing `x + 2` if `x` is None at that point. (There may be some advantages in certain corner cases.) In Scala, things are different, and you have a special type for missing elements, called `Option`. (Note that `null` also exists, like in Java or JavaScript, but you should never use it!)

An Option is either `None` or `Some(x)`. For example, if `x` is 3, and `val y = Some(2)`, the compiler will not let you write `y + 2` because + is not supported for Options. You are forced to look inside, which brings much more runtime safety. But how do you work with it, though? Let’s again compare typical Python implementations and the Scala “counterpart”.

would be, in Scala

In order to handle missing data, you also have the choice of using the `Try` class. A Try is like an Option, but instead it carries an error when the element is missing. For example, if you want to transform a String into a Double (float), returning NaN when the string is malformed, you could do

The same thing in Python would be```

Data representation

Scala has a nice way of representing complex data, which are “case classes”. A case class is a regular class with a lot of boilerplate added to it. There are similar to classes extending NamedTuple in Python.

For example,

is equivalent to

Printing the name of all adults in a list of Persons can for example be achieved by doing

which would be, in Python

Control flow

Control flow in Python essentially involves for loops and long “if-else” statements. In Scala, there is basically no loop (we work on collections instead) and “if-else” sequences are powerfully replaced by “pattern matching”. Pattern matching is like a switch, but it allows to deconstruct elements to extract their components. For example, you can do

which would be equivalent to

Object oriented

Python is often liked for its support for object oriented paradigm. I actually think that Scala is hard to beat in that regard, as it is very clean, intuitive and powerful. Let’s see a small class definition in Python, and its counterpart in Scala.

Wrap-up

With all of that, you should be ready to get started coding in Scala. As you will discover, most of the time you simply follow what your ide suggests, relying on the types when in doubt…

For reference, here are a handful of useful resources:

--

--