Get Started with Scala
Tags: scala, todayilearned, learning
Published: 2021-04-04 11:45:39

This article was originally posted on my [blog](https://eduardocribeiro.com/).

---

In the last few weeks, I started learning the basics about the [Scala](https://www.scala-lang.org/) programming language. I wanted to learn a language that was popular and effective in concurrent programming and distributed applications. In this article, I will talk about the basics of Scala, some cool aspects and features of the language that separate it from the most common languages like Java and Python, and provide a set of amazing resources to learn Scala and go from beginner to expert.

# What is Scala?

Scala is a general-purpose language that combines two programming paradigms: **object-oriented programming** and **functional programming**. Scala source-code can be compiled to Java bytecode, so it can run on the Java Virtual Machine (JVM), and is compatible with existing Java programs and libraries.

If you are familiar with more traditional OOP languages like Java, you will find most Scala code as not too difficult to read and understand. In Scala there are classes, methods, fields, and the overall syntax is not too different from Java. However, one difference between these two languages is that in Scala, **everything is an object**: even Java primitive types like `int` and `float`. Every variable is an object and every operator is a method.

As it was mentioned, Scala also combines the OOP paradigm with the advantages of functional programming. Functions are treated like "first-class citizens", as they are also variables (and therefore, objects). You can pass them as an argument to other functions or use them as a return value, for example.

Some other features of Scala that are worth mentioning are:

* **Type inference.** You can, but don't need to explicitly specify the data type of a variable or the return type of a function.
* **Immutability.** In Scala we usually operate with immutable values/objects. Any modification should just return another object. This is a major advantage for multithreaded or distributed environments, as it prevents a lot of race conditions.
* **Lazy Computation.** Lazy computation means evaluating an expression or calculating something not when the expression is declared, but only when the result is needed in another computation. You can declare a lazy variable using the keyword `lazy`.
* **Good set of collections.** Scala provides various classes and traits to collect and manage data, like `List`, `Seq`, `Set`, `Map`, etc.
* **Concurrency support and control.** Scala provides in its standard library the `Actor` class, which gives a higher level of abstraction for writing concurrent and distributed systems because we don't have to directly deal with explicit locking and thread management. There are also tools that support Scala in distributed and concurrent applications, like the [Akka](https://akka.io/) toolkit.

While Scala is a general-purpose language that can be used for a lot of things, and can basically be used for anything Java can be used for, its main application seems to be in **concurrent programming and distributed applications.**

# A Simple Example

Here is a very simple example in Scala, where we use a list to calculate the sum of a set of numbers. We then create a new list by appending a new element to the already existing list, and calculating the new sum of elements.

```scala
object Example {
    def main(args: Array[String]) = {
        val l = List(1, 2, 3)
        val lsum = l.sum
        println(s"$l - Sum: $lsum")

        val l2 = l :+ 4
        val l2sum = l2.sum
        println(s"$l2 - Sum: $l2sum")
    }
}
```

Here is a short description of the code:

* We define a `main` function inside the Example `object`, where all the code is contained.
* Declaring an `object` is like declaring a new class, and creating the singleton instance for it.
* We then use the `val` keyword to declare an immutable variable (constant), and we create a new `List` with the elements 1, 2 and 3.
* We use `l.sum` to calculate the sum of all the list elements.
* The `println()` function is then invoked to print to the console the contents of the file and the sum of all elements. We use **string interpolation** to insert in the string the value of the variables, using the `$` character.
* We use `:+` to append an element to the list. Notice that `l` is not modified, instead we use a new immutable variable `l2` to store the result.
* We then repeat the same operations for the new list `l2`.

Let's say this program was stored on a file called `FirstExample.scala`. We first need to compile the contents of the file to Java bytecode, and then we can execute the generated bytecode.

To compile, we can use `scalac` like so:

```
> scalac FirstExample.scala
```

And to execute the generated bytecode we can do:

```
> scala FirstExample
```

Here's what we can see on the console after we execute the program:

```text
List(1, 2, 3) - Sum: 6
List(1, 2, 3, 4) - Sum: 10
```

# Some Other Cool Things about Scala

## (Almost) Everything is an expression

For the most part, almost everything in Scala can be classified as an expression, meaning that it evaluates to a certain value. One thing that can be used as an expression in Scala, in contrast to most common languages, is an **if-statement**. That allows us to do stuff like this:

```scala
val value = if (something > 42) 55
    else if (something > 23) 45
    else if (anotherSomething > 84) 1000
    else 0
```

Another feature of Scala that also can be used as an expression is **code blocks**. Code blocks are groups of instructions or statements inside curly brackets; the value returned by the code block is the value generated by its last statement. We can then do stuff like this:

```scala
val aCodeBlock = {
    val localValue = 67
    localValue + 3 // value returned by the code block
}
```

The variable that is receiving the value from the code block would be assigned with the value 70.

## map, flatMap, filter and for-comprehensions

The 3 methods `map`, `flatMap` and `filter` are some of the most commonly used methods when dealing with data structures of any kind, and if you've done any significant programming in Scala, you likely already used them at some point. These methods allow us to do some powerful things in very little code, removing the need for many loops and iterations when using things like lists.

Let's start by creating a very simple `List`:

```scala
val l = List(1, 2, 3)
```

We can use the `map` method like so:

```scala
val l2 = l.map(_ + 1)
println(l2) // List(2, 3, 4)
```

This creates a new list, applying the function passed as an argument to `map` to every element of the list.

We can use `filter` to select only some elements from the list:

```scala
val l3 = l.filter(_ % 2 != 0)
println(l3) // List(1, 3)
```

This way, we create a new list `l3` containing only the odd elements of the original list.

The `flatMap` method is similar to the `map` method, but flattens the result of various lists into just one. Let's say we have the following function in our code, that receives an integer, and outputs a list containing the original value and the square of that value:

```scala
val toSquare = (x: Int) => List(x, x*x)
```

We can then use `flatMap` like so:

```scala
val l4 = l.flatMap(toSquare)
println(l4) // List(1, 1, 2, 4, 3, 9)
```

However, for more complex things, we might need to use a combination of these 3 methods, and the code might not be as readable as we want. Let's take another example, where we have two lists, one with numbers and the other with names, and we want to create strings representing the combination of all names with only the odd numbers.

```scala
val names = List("Bob", "Shirley")
val numbers = List(1, 2, 3)
```

With the methods shown above, we could do something like this:

```scala
val result = names.flatMap(name => numbers.filter(_ % 2 != 0).map(number => "" + name + number))
println(result) // List(Bob1, Bob3, Shirley1, Shirley3)
```

As you can see, it's not the most readable thing. Another way we can do it is by using **for-comprehensions:**

```scala
val result2 = for {
    name <- names
    number <- numbers if number % 2 != 0
} yield "" + name + number
println(result2) // List(Bob1, Bob3, Shirley1, Shirley3)
```

Much better!

## Pattern Matching

This is something that is present in some other programming languages, like [Haskell](https://www.haskell.org/), for example.

If you are familiar with C++, Java, or other popular languages, switch statements are nothing new to you. 

```scala
val value = 55
val order = value match {
    case 1 => "first"
    case 2 => "second"
    case 3 => "third"
    case _ => value + "th" // default case
}
```

However, in Scala we can do what is called **pattern matching:** instead of trying to match a variable against concrete values, we can match the variable against a certain structure, and then use its inner variables or values in the match expression. 

Like this:

```scala
val tuple = ("Bob", 23) // creating a tuple
val result = tuple match {
  case (name, age) => s"$name is $age years old"
  case _ => "Default case"
}
println(result) // Bob is 23 years old
```

or this:

```scala
val myList = List(1, 2, 3)
val result = myList match {
    case List(_, 2, _) => "This list contains 3 elements and has a 2 as the 2nd element"
    case _ => "Idk what this is"
}
```

# Some good resources to learn the basics of Scala

If you are interested in exploring what Scala has to offer, you can check out the following resources that I found useful for myself:

* [Scala at Light Speed](https://www.youtube.com/watch?v=-8V6bMjThNo&list=PLmtsMNDRU0BxryRX4wiwrTZ661xcp6VPM) - Fast-paced Scala course on YouTube, that covers the absolute basics. A good place to start 🙂
* [Scala Online Resources](https://docs.scala-lang.org/learn.html) - The official Scala website and documentation has a curated list of free (!) resources that allow you to master Scala and go from beginner to expert.
* [ScalaFiddle](https://scalafiddle.io/) - Lets you write Scala in your browser. If you want to explore and play with Scala before taking the time to install things locally, or if you just want to do quick experiments and tests, ScalaFiddle might be useful to you.

As with all programming languages, learning Scala is not just about watching content. Nothing replaces practice and actually writing code, so you can try to implement some basic algorithms in Scala, or solve some problems on [Leetcode](https://leetcode.com/) 🙂

# Conclusion

Scala is a language that I definitely want to learn more about in the future. Most importantly it's a door into a new paradigm that I never explored before, which is functional programming.
In the future, I will be doing more Scala posts, when I learn new stuff about the language, and hopefully also share some projects that use it 🙂

As always, thank you for reading, and until next time!

# References

* [Map, Flatmap and Filter in Scala](https://www.james-willett.com/scala-map-flatmap-filter/)

* [Features of Scala - JavaTPoint](https://www.javatpoint.com/features-of-scala)

* [Scala Features - Official Scala Documentation](https://docs.scala-lang.org/overviews/scala-book/scala-features.html)

* [Scala Mutable and Immutable Collections](https://docs.scala-lang.org/overviews/collections/overview.html)