Scala for Python developers
By: Antoine Doeraene
Tags: Programming, Python, Scala

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: