Scala is a programming language released in 2004 by Martin Odersky. It provides support for functional programming and is designed to be concise and compiled to Java bytecode so that a Scala application can be executed on a Java Virtual Machine (JVM). Let’s check at the core features of the language. ### Hello World First, let’s see how to implement a hello world in Scala:  We defined a `HelloWorld` object containing a `main` method. This method takes an array of `String` as an input. In the main, we called the method `println` which takes an object as an input to print something in the console. Meanwhile, `HelloWorld` is also part of the `io.teivah.helloworld` package. ### Values We can name the result of an expression using the `val` keyword. In the following example, both expressions are a valid way to define a value:  The type is optional. In the example, `v1` and `v2` are both typed as a String. The Scala compiler can infer the type of a value without having to explicitly declare it. This is known as type inference. A value in Scala is **immutable**. This means, the following code is not going to compile:  Last but not least, a value can be evaluated **lazily** using the `lazy` keyword:  In this case, `context` will not be evaluated during its declaration but during its first invocation. ### Variables A variable is a **mutable** value. It is declared with the `var` keyword.  Just like with values, the type is optional. Yet, a variable cannot be evaluated lazily. Furthermore, Scala is a **statically typed language**. The following code, for example, is invalid as we try to map an `Int` into a variable already defined as a `String`:  ### Blocks In Scala, we can combine expressions by surrounding them with `{}`. Let’s consider the `println()` function which takes an object as an input. The two following expressions are similar:  Note that for the second `println` the last expression (`i + 2`) is the result of the overall block. When we call a function with a single argument just like `println`, we can also omit the parenthesis:  ### Basic Types Scala is considered a pure object-oriented language because **every value is an object**. Hence, there is no primitive in Scala (like Java `int` for example). There are 8 basic types in Scala: * `Byte` * `Short` * `Int` * `Long` * `Float` * `Double` * `Char` * `Boolean`  Scala type hierarchy Every basic Scala type inherits from `AnyVal`. On the other side, `AnyRef` is an alias for `java.lang.Object`. Lastly, both `AnyVal` and `AnyRef` inherits from `Any`. ### String Interpolation Scala provides an elegant way to embed variable/value references directly in processed string literals. As a concrete example:  This is made possible by the `s` **interpolator** before the quotation mark. Otherwise, it would print `Hello $name!`. There are few interpolators provided by Scala but it is a customizable mechanism. We can create for example our own interpolator to handle JSON conversions like this: `println(json"{name: $name}")`. ### Array and List An array is also handled in Scala as an object:  Two things to highlight here. Firstly, the way to set elements. Instead of using `a[0]` like in many languages, we use the syntax `a(0)`. This is a syntactic sugar to let us call an object just as **if it was a function**. Under the hood, the compiler is calling a default method called `apply()` taking a single input (an `Int` in our case) to make it possible. Secondly, despite being declared as a `val` in this example, the `Array` object is mutable so we can change the value of indexes 0 and 1. `val` just enforces to not mutate **the reference**, not the corresponding object. An array can also be initialized this way:  This expression is similar than above. Moreover, because it is initialized with 5 and 2, the compiler infers `a` as an `Array[Int]`. To manage multi-dimensional arrays:  This code creates a two-dimensional array and initializes the very first element to 5. There are many different data structures composing the Scala standard library. One of them is the **immutable** `List`:  Compared to `Array`, modifying an index after having initialized a `List` will lead to a compilation error. ### Map A map can be initialized like this:  Note the `->` operator to associate a color key to its corresponding hexadecimal value. `Map` is an **immutable** data structure. Adding an element means creating another `Map`:  Meanwhile, the elements cannot be modified. In the case we need a mutable structure, we can use `scala.collection.mutable.Map`:  In this example, we mutated the _AK_ key. ### Methods/Functions: Basics We have to make the distinction between methods and functions. A method is a function that is a **member** of a class, trait or object (we are going those notions). Let’s see a basic method example:  Here we defined an `add` method with the `def` keyword. It took two `Int` as an input and returned an `Int`. Both inputs are **immutable** (in the sense that they are managed just like if they were declared as `val`). The `return` keyword is optional. The method will automatically return the last expression. Moreover, it’s worth mentioning that in Scala (compared to Java), `return` exits the **current method**, not the current block. One last thing to add, the **return type is optional**. The Scala compiler is also able to infer it. Yet, for the sake of code maintainability, it might be a good option to set it explicitly. Furthermore, a method without output can be written is both ways:  We can also return multiple outputs like this:  This prevents us from having to wrap a set of outputs in a specific object. Another syntactic sugar to mention. Let’s consider a `bar` method without arguments. We can call this method in both ways:  The best practice is to keep the parenthesis only if `bar` introduces a side-effect. Otherwise, we call `bar` like in the second expression. Also, Scala allows us to indicate that a method argument can be **repeated**. Just like in Java, this repeatable argument must be the last parameter:  Here, we iterate over each `args` element and we return an aggregated sum. Last but not least, we can also define default parameters value:  Invoking `default` without providing a value for `x` can be done in two ways. First, using the `_` operator:  Or, using named arguments like this:  ### Methods/Functions: Advanced #### Nested Methods In Scala, we can **nest method definitions**. Let’s consider the following example:  In this case, `mergesort2` method is used solely by `mergesort1`. To restrict its access, we may decide to set it `private` (we’ll see later on the different visibility levels). Yet, in Scala we can also decide to nest the second method into the first one like that:  `mergesort2` becomes available only in the scope of `mergesort1`. #### Higher-Order Functions Higher-order functions **take as parameters a function or return a function as a result**. As an example of a method taking a function as a parameter:  `f` is a function taking an `Int` as an input and returning an `Int`. In our example, `foo` delegates the execution to `f` by passing `i` to it. #### Function Literals Scala is considered as a functional language in the sense that **every function is a value**. It means we can express a function in a function literal syntax like that:  `increment` is a function with an `Int => Int` type (which could have been inferred by the Scala compiler). For each integer `x` it returns `x + 1`. If we take again the previous example, we could pass `increment` to `foo`:  We can also manage so-called anonymous functions:  The second parameter is a function without any name. #### Closure A closure in a function literal which **depends** on the value of one or more variable/value declared outside this function. A simple example:  Here, `foo` depends on `Pi` which is declared outside of `foo`. #### Partial Functions Let’s consider the following method to compute the speed from a distance and a time:  Scala allows us to **partially apply** `speed` by calling it only with a subset of the mandatory inputs:  Note that in this example, none of the parameters of `speed` have a default value. So in order to call it, we need to fill all the parameters. In this example, `partialSpeed` is a function of type `Float => Float`. Then, in the same way as we were calling `increment`, we can call `partialSpeed` like this:  #### Currying A method can define multiple parameter lists:  This method is doing exactly the same job than:  Yet, the way to call `multiply` is different:  Like requested by the method signature, we call it with two lists of parameters. Then, what if we call `multiply` with only one list of parameters?  In this case, we partially applied `multiply` which gives us in return an `Int => Int` function. What are the **benefits**? Let’s consider a function to send a message given a particular context:  As you can see, there’s an effort made to make this function pure. Instead of depending on an external context, we make it available as a parameter of the `send` function. Yet, it might be somewhat tedious to have to pass this context during every single call of `send`. Or maybe a function does not need to know about the context. One solution may be to partially apply `send` with a predefined context and to manage an `Array[Byte] => Unit` function. Another solution is to curry `send` and make the `context` parameter `implicit` like this:  How can we call `send` in this case? We can define an `implicit` context before to call `send`:  The `implicit` keyword means that for every function managing an implicit `Context` parameter, we don’t even need to pass it. It will **automatically** be mapped by the Scala compiler. In our case, `send` manages the `Context` object as a potential implicit (we can also decide to pass it explicitly). So, we can simply call `send` with the first argument list. ### Classes A class in Scala is a similar concept than in Java:  `Point` exposed a default `(Int, Int)` constructor because of the syntax line 1. Meanwhile, `x` and `y` are two members of the class. A class can also contain a collection of methods just like `move` in the previous example. We can instantiate `Point` with the `new` keyword:  A class can be abstract meaning it cannot be instantiated. ### Case Classes Case classes are a particular kind of classes. If you are familiar with DDD (Domain Driven Design), a case class is a **value object**. By default, a case class is **immutable**:  The value of `x` and `y` cannot be changed. A case class must be instantiated without `new`:  Case classes (compared to regular classes) are compared by value (and not by reference):  ### Objects An object in Scala is a **singleton**:  Objects are defined with the `object` keyword (👏). ### Traits Traits are in a way similar to Java interfaces. They are used to **share interfaces between classes but also fields**. As an example:  A trait method can also have a default implementation. Traits cannot be instantiated but they can be extended by classes and objects. ### Visibility In Scala, every member of a class/object/trait is public by default. There are two other access modifiers: * `protected`: members are only accessible from sub-classes * `private`: members are only accessible from the current class/object Furthermore, we can also have a more granular way to restrict access by specifying a package in which the restriction is applied. Let’s consider a class `Foo` in a `bar` package. If we want to make a method private only outside of `bar` we can do it this way:  ### Generics Generics is also a feature provided by Scala:  To instantiate a generic class:  ### If-else If-else syntax is similar in Scala than in several other languages:  Yet, in Scala an if-else statement is also an **expression**. It means we can, for example, define methods like this:  ### Loops A basic loop can be implemented like this:  `to` means from 0 to 10 included whereas `until` means from 0 to 10 excluded. We can also loop over two elements:  In this example we iterated over all the possible tuple combinations: a=0, b=0 a=0, b=1 a=0, b=2 a=1, b=0 a=1, b=1 a=1, b=2 We can also include conditions in the for. Let’s consider the following list of elements:  If we need to iterate over each element of `list` and consider only the even integers, we can do it this way:  Moreover, Scala provides so-called **for comprehensions** to create sequence of elements with the form `for() yield element`. As an example:  In this example, we created a collection of even integers by iterating over each element and _yielding_ it in case it is even. As a result, `sub` will be inferred as a sequence of integers (a `Seq` object, the parent of `List`). In the same way than with if-else statement, for is also an expression. So we can also define methods like this:  ### Pattern Matching Pattern matching is a mechanism to check a value against a given pattern. It is an enhanced version of the Java `switch` statement. Let’s consider a simple function to translate an integer into a string:  Scala adds a bit of syntactic sugar to implement an equivalent this way:  First, we removed the `return` statements. Then, `matchB` function becomes a pattern matcher as we removed the block statement after the function definition. Anything else apart from some sugar? Pattern matching is a great addition to case classes. Let’s consider an example taken from [Scala documentation](https://docs.scala-lang.org/tour/pattern-matching.html). We want to return a `String` depending on a notification type. We define an abstract class `Notification` and two case classes `Email` and `SMS`:  The most elegant way to do it in Scala is to use **pattern matching** on the notification:  This mechanism allows us to **cast** the given `notification` and to automatically parse the parameters we are interested in. For example, in the case of an email, maybe we are not interested in displaying the `body` so we simply omit it with `_` keyword. ### Exceptions Let’s consider the concrete use case where we need to print the number of bytes from a given file. To perform the I/O operation, we are going to use `java.io.FileReader` which may throw exceptions. The most common way to do it if you are a Java developer would be something like this using a try/catch statement:  The second way to implement it is somewhat similar to Java `Optional`. As a reminder, `Optional` is a container brought in Java 8 for optional values. In Scala, `Try` is a **container for success or failures**. It is an abstract class, extended by two case classes `Success` and `Failure`.  We first wrap the creation of a new `FileReader` in a `Try` call. We use a map to convert an eventual `FileReader` to an `Int` by calling the `read` method. As a result, we get a `Try[Int]`. Then, we can use pattern matching to determine the type of `tried`. ### Implicit Conversions Let’s analyze the following example:  We defined two case classes `Foo` and `Bar`. Meanwhile, an object `Consumer` exposes a `consume` method taking a `Foo` in parameter. In `Test`, we call `Consumer.consume()` but **not with a** `Foo` as required by the signature of the method but with a `Bar`. How is this possible? In Scala, we can define implicit conversions between two classes. In the last example, we simply need to describe how to convert a `Bar` to a `Foo`:  If this method `barToFoo` is imported, the Scala compiler will make sure that we can call `consumer` with **either** a `Foo` or a `Bar`. ### Concurrency To handle concurrency, Scala was initially based on the [**actor model**](https://en.wikipedia.org/wiki/Actor_model). Scala was providing the `scala.actors` library. Yet, since Scala 2.10 this library became deprecated in favor of [**Akka actors**](https://doc.akka.io/docs/akka/current/index-actors.html?language=scala). Akka is a set of libraries for implementing concurrent and distributed applications. Nonetheless, we can also use Akka only at the scale of a single process. The main idea is to manage actors as a **primitive for concurrent computation**. An actor can send messages to other actors, receive and react to messages and spawn new actors.  Example of communications within an actor system Just like other concurrent computation models like CSP (Communicating Sequential Processes), the key is to communicate **through messages** instead of sharing memory between different threads.  Credits: baloocartoons.com Scala is a very elegant language. Yet, the learning curve is not that small compared to other languages like Go for example. Reading an existing Scala code as a beginner might be somewhat difficult. But once you start to master it, developing an application can be done in a very efficient way. ### Further Reading [**Documentation | Scala Documentation** _Install Scala on your computer and start writing some Scala code!_docs.scala-lang.org](https://docs.scala-lang.org/ "https://docs.scala-lang.org/")[](https://docs.scala-lang.org/)