Home Application-development Building Applications with Scala

Building Applications with Scala

By Diego Pacheco
books-svg-icon Book
Subscription
$10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
BUY NOW $10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
Subscription
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
  1. Free Chapter
    Introduction to FP, Reactive, and Scala
About this book

Scala is known for incorporating both object-oriented and functional programming into a concise and extremely powerful package. However, creating an app in Scala can get a little tricky because of the complexity the language has. This book will help you dive straight into app development by creating a real, reactive, and functional application. We will provide you with practical examples and instructions using a hands-on approach that will give you a firm grounding in reactive functional principles.

The book will take you through all the fundamentals of app development within Scala as you build an application piece by piece. We’ve made sure to incorporate everything you need from setting up to building reports and scaling architecture. This book also covers the most useful tools available in the Scala ecosystem, such as Slick, Play, and Akka, and a whole lot more. It will help you unlock the secrets of building your own up-to-date Scala application while maximizing performance and scalability.

Publication date:
December 2016
Publisher
Packt
Pages
344
ISBN
9781786461483

 

Chapter 1. Introduction to FP, Reactive, and Scala

In our first chapter, we will learn the basic concepts of Functional Programing (FP), reactive programming, and the Scala language. These concepts are listed as follows:

  • Setting up a Scala development environment with Eclipse Scala IDE.

  • Basic constructs of the language like var, val, for, if, switch, and operator overload.

  • The difference between FP and object-oriented programming.

  • Principles of pure FP: immutability, no side effects, state discipline, composition, and higher order functions.

  • Concepts of FP such as lambda, recursion, for comprehensions, partial functions, Monads, currying, and functions.

  • Pattern Matcher, recursion, reflection, package objects, and concurrency.

Let's get going!

 

Functional programming


FP is not new at all. The very first implementation of FP is Lisp and is dated from the 1950s. Currently, we are living in a post-functional programming era, where we have the strong math principles and ideas from the 50s mixed with the most modern and beautiful piece of engineering, also know as the Java Virtual Machine (JVM). Scala is a post-functional programming language built on top of the JVM. Being on top of the JVM gives us a lot of benefits such as the following:

Scala is a post-functional programming language built on top of the JVM. Being on top of the JVM gives us a lot of benefits such as the following:

  • Reliability and performance: Java is used by 10 out of 10 top websites we have currently, like Netflix, Apple, Uber, Twitter, Yahoo, eBay, Yelp, LinkedIn, Google, Amazon, and many others. JVM is the best solution at scale and is battle-tested by these web-scale companies.

  • Native JVM eco-system: Full access to all of the Java ecosystem including frameworks, libraries, servers, and tools.

  • Operations leverage: Your operation team can run Scala in the same way they run Java.

  • Legacy code leverage: Scala allows you to easily integrate Scala code with Java code. This feature is great because it enables Java legacy system integration inside the box.

  • Java interoperability: A code written in Scala can be accessed in Java.

Scala was created in 2001 at EPFL by Martin Odersky. Scala is a strong static-typed language, and was inspired by another functional language called Haskell. Scala addresses several criticisms of the Java language, and delivers a better developer experience through less code and more concise programs, without losing performance.

Scala and Java share the same infrastructure as the JVM, but in terms of design, Scala is a different language in comparison with Java. Java is an imperative object-oriented language and Scala is a post-functional, multiparadigm programing language. FP works with different principles than object-oriented programing (OOP). OOP got very popular and well established in enterprise thanks to languages like Java, C#, Ruby, and Python. However, languages like Scala, Clojure, F#, and Swift are gaining a huge momentum, and FP has grown a lot in the last 10 years. Most of the new languages are pure functional, post-functional, or hybrid (like Java 8). In this book, you will see Scala code compared with Java code so you can see by yourself how Scala is way more compact, objective, and direct than Java and imperative OOP languages.

FP started at academia and spread to the world; FP is everywhere. Big Data and Stream processing solutions like Hadoop and Spark (built on top of Scala and Akka) are built on top of FP ideas and principles. FP spread to UI with RxJavaScript - you can even find FP in a database with Datomic (Clojure). Languages like Clojure and Scala made FP more practical and attractive to enterprise and professional developers. In this book, we will be exploring both principles and practical aspects of the Scala language.

 

Principles of functional programming


FP is a way of thinking, a specific style of constructing and building programs. Having an FP language helps a lot in terms of syntax, but at the end of the day, it's all about ideas and developer mindset. FP favors disciplined state management and immutability in a declarative programming way rather than the imperative programming mostly used by OOP languages such as Java, Python, and Ruby.

FP has roots in math back to Lambda calculus - a formal system developed in the 1930s. Lambda calculus is a mathematical abstraction and not a programming language, but it is easy to see its concepts in programming languages nowadays.

Imperative programming uses statements to change the program state. In other words, this means you give commands to the program to perform actions. This way of thinking describes a sequence of steps on how the program needs to operate. What you need to keep in mind is the kind of style focus on how FP works in a different way, focusing on what the program should accomplish without telling the program how to do it. When you are coding in FP, you tend to use fewer variables, for loops, and IFS, and write more functions and make function composition.

The following are the CORE principles of FP:

  • Immutability

  • Disciplined state

  • Pure functions and no side effects/disciplined states

  • First class functions and high order functions

  • Type systems

  • Referential transparency

Let's understand these principles in detail.

Immutability

The concept of immutability is the CORE of FP, and it means that once you assign a value to something, that value won't change. This is very important, because it eliminates side effects (anything outside of the local function scope), for instance, changing other variables outside the function. Immutability makes it easier to read code, because you know the function that you are using is a pure function. Since your function has a disciplined state and does not change other variables outside of the function, you don't need to look at the code outside the function definition. This sounds like you're not working with state at all, so how would it be possible to write professional applications this way? Well, you will change state but in a very disciplined way. You will create another instance or another pointer to that instance, but you won't change that variable's value. Having immutability is the key to having better, faster, and more correct programs, because you don't need to use locks and your code is parallel by nature.

Disciplined state

Shared mutable state is evil, because it is much harder to scale and to run it concurrently. What is shared mutable state? A simple way to see it is as a global variable that all your functions have access to. Why is this bad? First of all, because it is hard to keep this state correct since there are many functions that have direct access to this state. Second, if you are performing refactoring, this kind of code is often the hardest to refactor as well. It's also hard to read this code. This is because you can never trust the local method, since your local method is just one part of the program. And with mutable state, you need to look up for all the functions that use that variable, in order to understand the logic. It's hard to debug for the very same reason. When you are coding with FP principles in mind, you avoid, as much as possible, having a shared mutable state. Of course you can have state, but you should keep it local, which means inside your function. This is the state discipline: you use state, but in a very disciplined way. This is simple, but it could be hard especially if you are a professional developer, because this aspect is now usual to see in enterprise languages such as Java, .NET, Ruby, and Python.

Pure functions and no side effects

Pure functions are the ones with no side effects. Side effects are bad, because they are unpredictable and make your software hard to test. Let's say you have a method that receives no parameters and returns nothing--this is one of the worst things we could have, because how do you test it? How can you reuse this code? This is not what we call a pure function. What are the possible side effects? Database call, global variables, IO call, and so on. This makes sense, but you cannot have a program with just pure functions, because it won't be practical.

First-class functions and higher-order functions

First-class means that the language treats functions as first-class citizens. In other words, it means having language support to pass functions as arguments to other functions and to return values as functions. First-class function also implies that the language allows you to store functions as variables or any other data structure.

Higher-order functions are related to First-class functions, but they are not the same thing. Higher-order functions often means language support for partial functional application and Currying. Higher-order functions are a mathematical concept where functions operate with other functions.

Partial functions are when you can fix a value (argument) to a particular function, which you may or may not change later on. This is great for function composition.

Currying is a technique to transform a function with multiple parameters in a sequence of functions with each function having a single argument. Scala language does not force currying, however, languages like ML and Haskell almost always use this kind of technique.

Type systems

Type system is all about the compiler. The idea is simple: you create a type system, and by doing so, you leverage the compiler to avoid all kinds of mistakes and errors. This is because the compiler helps in making sure that you only have the right types as arguments, turn statements, function composition, and so on. The compiler will not allow you do make any basic mistakes. Scala and Haskell are examples of languages that are Strong-type. Meanwhile, Common Lisp, Scheme, and Clojure are dynamic languages that may accept wrong values during compilation time. One of the biggest benefits of the strong type system is that you have to write fewer tests, because the compiler will take care of several issues for you. For instance, if you have a function that receives a string, it could be dangerous, because you can pass pretty much anything in a string. However, if you have a function that receives a type called salesman, then you don't write a validation to check if it is a salesman. All this may sound silly, but in a real application, this saves lots of lines of code and makes you program better. Another great benefit of strong typing is that you have better documentation, as your code becomes your documentation, and it's way more clear what you can or can't do.

Referential transparency

Referential transparency is a concept which works close with pure functions and immutability since your program has fewer assignment statements, and often when you have it, you tend to never change that value. This is great because you eliminate side effects with this technique. During program execution, any variable can be replaced since there are no side effects, and the program becomes referentially transparent. Scala language makes this concept very clear the moment you declare a variable.

 

Installing Java 8 and Scala 2.11


Scala requires JVM to work, so we need get the JDK 8 before installing Scala. Go to the Oracle website, and download and install JDK 8 from http://www.oracle.com/technetwork/pt/java/javase/downloads/index.html.

Once you've downloaded Java, we need to add Java to the PATH variable; otherwise, you can use the terminal. We do this as follows:

$ cd ~/
$ wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "
http://download.oracle.com/otn-pub/java/jdk/8u77-b03/jdk-8u77-linux-i586.tar.gz"
$ tar -xzvf $ jdk-8u77-linux-x64.tar.gz 
$ rm -f jdk-8u77-linux-x64.tar.gz

The next step is to create the environment variable called JAVA_HOME, and to put the Java 8 binaries in the PATH variable. In Linux, we need to edit the ~/.bashrc file, and export the variables we need, like in the following:

export JAVA_HOME=~/jdk1.8.0_77
export PATH=$PATH:$JAVA_HOME/bin

Save the file, and then on the same terminal we need to source the file via $ source ~/.bashrc

Now we can test our Java 8 installation. Just type in $ java -version. You should see something like the following:

$ java -version
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) Server VM (build 25.77-b03, mixed mode)

Let's get started. We will be using the latest Scala version 2.11.8. However, the code inside this book should work with any Scala 2.11.x version. First of all, let's download Scala from http://www.scala-lang.org/.

Scala works on Windows, Mac, and Linux. For this book, I will show how to use Scala on Ubuntu Linux(Debian-based). Open your browser and go to http://www.scala-lang.org/download/.

Download scala 2.11.8: it will be a TGZ file. Extract it and add it to your path; otherwise, you can use the terminal. Do this as follows:

$ cd ~/
$ wget http://downloads.lightbend.com/scala/2.11.8/scala-2.11.8.tgz
$ tar -xzvf scala-2.11.8.tgz
$ rm -rf scala-2.11.8.tgz

The next step is to create the environment variable called SCALA_HOME, and to put the Scala binaries in the PATH variable. In Linux, we need to edit the ~/.bashrc file and export the variables we need, like in the following:

export SCALA_HOME=~/scala-2.11.8/
export PATH=$PATH:$SCALA_HOME/bin

Save the file, and then, on the same terminal, we need to source the file via $ source ~/.bashrc.

Now we can test our Scala installation. Just type in $ scala -version. You should see something like the following:

$ scala -version
Scala code runner version 2.11.8 -- Copyright 2002-2016, LAMP/EPFL

You have successfully installed Java 8 and Scala 2.11. Now we are ready to start learning the FP principles in Scala. For this, we will be using the Scala REPL in the beginning. Scala REPL is bundled with the default Scala installation, and you just need to type $ scala in your terminal as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala>
Scala REPL

Congratulations! You have installed Java 8 and Scala 2.11 successfully.

 

Read Eval Print and Loop - REPL


Read Eval Print and Loop (REPL) is also know as a language shell. Many other languages have shells, like Lisp, Python, and Ruby for instance. The REPL is a simple environment to experiment the language in. It's possible to write very complex programs using REPL, but this is not the REPL goal. Using REPL does not invalidate the usage of an IDE like Eclipse or IntelliJ IDEA. REPL is ideal for testing simple commands and programs without having to spend much time configuring projects like you do with an IDE. The Scala REPL allows you to create a variable, functions, classes, and complex functions as well. There is a history of every command you perform; there is some level of autocomplete too. As a REPL user, you can print variable values and call functions.

 

Scala Hello World using the REPL


Let's get started. Go ahead, open your terminal, and type $ scala in order to open the Scala REPL. Once the REPL is open, you can just type "Hello World". By doing this, you perform two operations: eval and print. The Scala REPL will create a variable called res0, and store your String there. Then it will print the content of the res0 variable.

Scala REPL Hello World program

We will see how to create Hello World program in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> "Hello World"
res0: String = Hello World
scala> 

Scala is a hybrid language, which means it is object-oriented and functional as well. You can create classes and objects in Scala. Next we will create a complete Hello World application using classes.

Scala object-oriented HelloWorld program

We will see how to create object-oriented HelloWorld program in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> object HelloWorld {
     |   def main(args:Array[String]) = println("Hello World")
     | }
defined object HelloWorld
scala> HelloWorld.main(null)
Hello World
scala>

The first thing you need to realize is that we use the word object instead of class. The Scala language has different constructs compared to Java. Object is a singleton in Scala. It's the same as coding the singleton pattern in Java.

Next we see the word def that is used in Scala to create functions. In the preceding program, we create the main function similar to the way we do it in Java, and we call the built-in function println in order to print the String Hello World. Scala imports some Java objects and packages by default. Coding in Scala does not require you to type, for instance, System.out.println("Hello World"), but you can if you want. Let's take a look at it in the following code:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> System.out.println("Hello World") 
Hello World
scala>

We can and we will do better. Scala has some abstractions for a console application, so we can write this code with a lesser number of lines of code. To accomplish this goal, we need to extend the Scala class App. When we extend from App, we perform inheritance and we don't need to define the main function. We can just put all the code in the body of the class, which is very convenient and makes the code clean and simple to read.

Scala HelloWorld App in the Scala REPL

We will see how to create Scala HelloWorld App in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> object HelloWorld extends App {
     |  println("Hello World")
     | }
defined object HelloWorld
scala> HelloWorld
object HelloWorld
scala> HelloWorld.main(null)
Hello World
scala>

After coding the HelloWorld object in the Scala REPL we can ask the REPL what HelloWorld is, and as you might realize, the REPL will answer that HelloWorld is an object. This is a very convenient Scala way to code console applications, because we can have a Hello World application with just three lines of code. Sadly, to have the same program in Java, it required way more code. Java is a great language for performance, but it is a verbose language compared with Scala, for instance.

Java HelloWorld application

We will see how to create Java HelloWorld application as follows:

    package scalabook.javacode.chap1; 
 
    public class HelloWorld { 
      public static void main(String args[]){ 
        System.out.println("Hellow World"); 
      } 
    } 

The Java app required six lines of code, while in Scala, we were able to do the same with 50% less code (three lines of code). This is a very simple application. When we are coding complex applications, this difference gets bigger, as a Scala application ends up with way less code than Java.

Remember, we use an object in Scala in order to have a Singleton (Design Pattern that makes sure you have just one instance of a class), and if we want the same in Java, the code would be something like the following:

    package scalabook.javacode.chap1; 
 
    public class HelloWorldSingleton { 
   
      private HelloWorldSingleton(){} 
   
      private static class SingletonHelper{ 
        private static final HelloWorldSingleton INSTANCE =  
        new HelloWorldSingleton(); 
      } 
   
      public static HelloWorldSingleton getInstance(){ 
        return SingletonHelper.INSTANCE; 
      } 
   
      public void sayHello(){ 
        System.out.println("Hello World"); 
      } 
   
      public static void main(String[] args) { 
        getInstance().sayHello(); 
      } 
    } 

It's not just about the size of the code, but also about consistency and the language providing more abstractions for you. If you write less code, you will have fewer bugs in your software at the end of the day.

 

Scala language - the basics


Scala is a statically typed language with a very expressive type system which enforces abstractions in a safe yet coherent manner. All values in Scala are Java objects (primitives which are unboxed at runtime), because at the end of the day, Scala runs on the Java JVM. Scala enforces immutability as a core FP principle. This enforcement happens in multiple aspects of the Scala language, for instance, when you create a variable, you do it in an immutable way, when you use an collection, you will use a immutable collection. Scala also lets you use mutable variables and mutable structures, but by design, it favors immutable ones.

 

Scala variables - var and val


When you are coding in Scala, you create variables using the operator var, or you can use the operator val. The operator var allows you to create a mutable state, which is fine as long as you make it local, follow the CORE-FP principles and avoid a mutable shared state.

Scala REPL var usage

We will see how to use var in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
    
scala> var x = 10
x: Int = 10
    
scala> x
res0: Int = 10

scala> x = 11
x: Int = 11
    
scala> x 
res1: Int = 11
    
scala> 

However, Scala has a more interesting construct called val. Using the val operator makes your variables immutable, and this means you can't change the value once you've set it. If you try to change the value of the val variable in Scala, the compiler will give you an error. As a Scala developer, you should use the variable val as much as possible, because that's a good FP mindset, and it will make your programs better. In Scala, everything is an object; there are no primitives -- the var and val rules apply for everything it could but an Int or String or even a class.

Scala val usage at the Scala REPL

We will see how to use val in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val x = 10
x: Int = 10
scala> x
res0: Int = 10
scala> x = 11
<console>:12: error: reassignment to val
       x = 11
         ^
scala> x
res1: Int = 10
scala>
 

Creating immutable variables


Right now, let's see how we define the most common types in Scala such as Int, Double, Boolean, and String. Remember, you can create these variables using val or var depending on your needs.

Scala variable type in the Scala REPL

We will see Scala variable type in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val x = 10
x: Int = 10
scala> val y = 11.1
y: Double = 11.1
scala> val b = true
b: Boolean = true
scala> val f = false
f: Boolean = false
scala> val s = "A Simple String"
s: String = A Simple String
scala>

For the variables in the preceding code, we did not define the type. Scala language figures it out for us. However, it is possible to specify the type if you want. In Scala, the type comes after the name of the variable.

Scala variables with explicit typing at the Scala REPL

We will see Scala variables with explicit typing at Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val x:Int = 10
x: Int = 10
scala> val y:Double = 11.1
y: Double = 11.1
scala> val s:String = "My String "
s: String = "My String "
scala> val b:Boolean = true
b: Boolean = true
scala>
 

Scala conditional and loops statements


Like any other language, Scala has support for conditional statements like if and else. While Java has a switch statement, Scala has a more powerful and functional structure called Pattern Matcher, which we will cover later in this chapter. Scala allows you to use if statements during variable assignments, which is very practical as well as useful.

If statements in Scala REPL

We will see how to use if statements in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val x = 10
x: Int = 10
scala> if (x == 10) 
     | println ("X is 10")
X is 10
scala> val y = if (x == 10 ) 11
y: AnyVal = 11
scala> y
res1: AnyVal = 11
scala>

In the preceding code, you can see that we set the variable y based on an if condition. Scala if conditions are very powerful, and they also can be used in return statements.

If statements in return statements in Scala REPL

We will see how to use if statements in return statements in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val x = 10
x: Int = 10
scala> def someFunction = if (x == 10) "X is 10"
someFunction: Any
scala> someFunction
res0: Any = X is 10
scala>

Scala supports else statements too, and you also can use them in variables and return statements as wellas follows:

~$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val x = 10
x: Int = 10
scala> if (x==10){
     |   println("X is 10")
     | } else {
     |   println ("X is something else")
     | }
X is 10
scala>

Now you will learn how to use for loops in Scala. For loops are very powerful in Scala. We will start with the basics and later we will move on to functional loops used for comprehensions, also know as List comprehensions.

In Scala, for loops work with ranges, which is another Scala data structure that represents numbers from a starting point to an end point. The range is created using the left arrow operator(<-). Scala allows you to have multiple ranges in the same for loop as long as you use the semicolon(;).

You also can use if statements in order to filter data inside for loops, and work smoothly with List structures. Scala allows you to create variables inside a for loop as well. Right now, let's see some code which illustrates the various for loop usages in Scala language.

Basic for loop in Scala REPL

We will see how to use basic for loop in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> for ( i <- 1 to 10)
     | println("i * " + i + " = " +  i * 10)
i * 1 = 10
i * 2 = 20
i * 3 = 30
i * 4 = 40
i * 5 = 50
i * 6 = 60
i * 7 = 70
i * 8 = 80
i * 9 = 90
i * 10 = 100
scala> 

Right now, we will create a for loop using a Scala data structure called List. This is very useful, because in the first line of code, you can define a List as well as set its values in the same line. Since we are using the List structure, you don't need to pass any other argument besides the List itself.

For with List in Scala REPL

We will see how to use for with List in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val listOfValues = List(1,2,3,4,5,6,7,8,9,10)
listOfValues: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> for ( i<- listOfValues ) println(i)
1
2
3
4
5
6
7
8
9
10
scala>

Next, we can use for loops with if statements in order to apply some filtering. Later in this book, we will approach a more functional way to approach filtering using functions. For this code, let's say we want to get just the even numbers on the list and print them.

For with if statements for filtering - Scala REPL

We will see how to use for with if statements in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val listOfValues = List(1,2,3,4,5,6,7,8,9,10)
listOfValues: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> for ( i<- listOfValues ) if  (i % 2== 0) println(i)
2
4
6
8
10
scala>

Java code for filtering even numbers

In Scala language, we just need two lines of code to perform this filtering, whereas in Java it would have required at least eleven lines of code as you see in the following code:

    package scalabook.javacode.chap1; 
 
    import java.util.Arrays; 
    import java.util.List; 
 
    public class ForLoopsEvenNumberFiltering { 
      public static void main(String[] args) { 
        List<Integer> listOfValues = Arrays.asList( 
          new Integer[]{1,2,3,4,5,6,7,8,9,10}); 
        for(Integer i : listOfValues){ 
          if (i%2==0) System.out.println(i); 
        } 
      } 
    } 
 

For comprehensions


Also known as list or sequence comprehensions, for comprehensions are one of the FP ways to perform loops. This is a language support to create List structure or collections based on other collections. This task is performed in a SetBuilder notation. Another way to accomplish the same goal would be by using the Map and filter functions, which we will cover later in this chapter. For comprehensions can be used in a generator form, which would introduce new variables and values, or in a reductionist way, which would filter values resulting into a new collection or sequence. The syntax is: for (expt) yield e, where the yield operator will add new values to a new collection/sequence that will be created from the original sequence.

For comprehension in Scala REPL

We will see how to use for comprehension in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val names = Set("Diego", "James", "John", "Sam", "Christophe")
names: scala.collection.immutable.Set[String] = Set(John, Sam, Diego, James, Christophe)
scala> 
scala> val brazilians = for {
     |   name <- names  
     |   initial <- name.substring(0, 1)
     |     } yield if (name.contains("Die")) name
brazillians: scala.collection.immutable.Set[Any] = Set((), Diego)
scala>

In the preceding code, we create a set of names. As you can see, Scala, by default, prefers immutable data structures and uses immutable.Set. When we apply the for loop, we are simply filtering only the names which contain a specific substring, and then, using the yield operator, we are creating a new Set structure. The yield operator will keep the structure you are using. For instance, if we use List structure, it would create a List instead of a Set structure, the yield operator will always keep the same data collection you have on the variable. Another interesting aspect of the preceding code is the fact that we are holding the result of the for comprehension in a variable called Brazilians. Java does not have for comprehensions, but we could use similar code although it would require way more lines of code.

Java code for performing filtering with collections

We will see how to use Java code for performing filtering with collections as follows:

    package scalabook.javacode.chap1; 
 
    import java.util.LinkedHashSet; 
    import java.util.Set; 
 
    public class JavaNoForComprehension { 
      public static void main(String[] args) { 
     
        Set<String> names = new LinkedHashSet<>(); 
        Set<String> brazillians = new LinkedHashSet<>(); 
     
        names.add("Diego"); 
        names.add("James"); 
        names.add("John"); 
        names.add("Sam"); 
        names.add("Christophe"); 
     
        for (String name: names){ 
          if (name.contains("Die")) brazillians.add(name);  
        } 
     
        System.out.println(brazillians); 
      } 
    } 
 

Scala collections


In the previous section, we saw how to create the List and Set structures in Scala in an immutable way. Now we will learn to work with the List and Set structures in a mutable way, and also with other collections such as sequences, tuples, and Maps. Let's take a look at the Scala collections hierarchy tree, as shown in the following diagram:

Now let's take a look at the Scala Seq class hierarchy. As you can see, Seq is traversable as well.

Scala collections extend from traversable, which is the main trait of all collection's descends. List structures, for instance, extend from Seq class hierarchy, which means sequence - List is a kind of sequence. All these trees are immutable or mutable depending on the Scala package you end up using.

Let's see how to perform basic mutable operations with List structures in Scala. In order to have filter and removal operations, we need use a Buffer sequence as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> var ms = scala.collection.mutable.ListBuffer(1,2,3)
ms: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3)
scala> ms += 4
res0: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4)
scala> ms += 5
res1: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5)
scala> ms += 6
res2: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6)
scala> ms(1)
res3: Int = 2
scala> ms(5)
res4: Int = 6
scala> ms -= 5
res5: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 6)
scala> ms -= 6
res6: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4)
scala>

Let's see the next set of code.

Creating, removing, and getting an item from a mutable list in Scala REPL

We will see how to create, remove, and get an item from a mutable list in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> var names = scala.collection.mutable.SortedSet[String]("Diego", "Poletto", "Jackson")
names: scala.collection.mutable.SortedSet[String] = TreeSet(Diego, Jackson, Poletto)
scala> names += "Sam"
res2: scala.collection.mutable.SortedSet[String] = TreeSet(Diego, Jackson, Poletto, Sam)
scala> names("Diego")
res4: Boolean = true
scala> names -= "Jackson"
res5: scala.collection.mutable.SortedSet[String] = TreeSet(Diego, Poletto, Sam)
scala>

Have you ever wanted to return multiple values in a method? Well, in Java you have to create a class, but in Scala, there is a more convenient way to perform this task, and you won't need to create new classes each time. Tuples allow you to return or simply hold multiple values in methods without having to create a specific type.

Scala tuples

We will see Scala tuples as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val config = ("localhost", 8080)
config: (String, Int) = (localhost,8080)
scala> config._1
res0: String = localhost
scala> config._2
res1: Int = 8080
scala>

Scala has special methods called _1 and _2 which you can use to retrieve a tuple's values. The only thing you have to keep in mind is the fact that values are kept in the order of insertion in the tuple.

Scala has a very practical and useful collection library. A Map, for instance, is a key/value pair that can be retrieved based on the key, which is unique. However, Map values do not need to be unique. Like other Scala collections, you have mutable and immutable Map collections. Keep in mind that Scala favors immutable collections over mutable ones.

Scala immutable Map in Scala REPL

We will see Scala immutable Map in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val numbers = Map("one"   -> 1, 
     |                   "two"   -> 2,
     |                   "three" -> 3,
     |                   "four"  -> 4,
     |                   "five"  -> 5,
     |                   "six"   -> 6,
     |                   "seven" -> 7,
     |                   "eight" -> 8,
     |                   "nine"  -> 9,
     |                   "ten"   -> 10)
numbers: scala.collection.immutable.Map[String,Int] = Map(four -> 4, three -> 3, two -> 2, six -> 6, seven -> 7, ten -> 10, five -> 5, nine -> 9, one -> 1, eight -> 8)
scala> 
scala> numbers.keys
res0: Iterable[String] = Set(four, three, two, six, seven, ten, five, nine, one, eight)
scala> 
scala> numbers.values
res1: Iterable[Int] = MapLike(4, 3, 2, 6, 7, 10, 5, 9, 1, 8)
scala> 
scala> numbers("one")
res2: Int = 1
scala>

As you can see, Scala uses scala.collection.immutable.Map when you create a Map using Map(). Both keys and values are iterable, and you can have access to all the keys with the keys method or to all the values using the values method.

Scala mutable Maps at Scala REPL

We will see Scala mutable Map in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val map = scala.collection.mutable.HashMap.empty[Int,String]
map: scala.collection.mutable.HashMap[Int,String] = Map()
scala> map += (1 -> "one")
res0: map.type = Map(1 -> one)
scala> map += (2 -> "two")
res1: map.type = Map(2 -> two, 1 -> one)
scala> map += (3 -> "three")
res2: map.type = Map(2 -> two, 1 -> one, 3 -> three)
scala> map += (4 -> "mutable")
res3: map.type = Map(2 -> two, 4 -> mutable, 1 -> one, 3 -> three)
scala> 

If you are dealing with mutable state, you have to be explicit and this is great in Scala, because it increases developers' awareness and avoids mutable shared state by default. So, in order to have a mutable Map, we need to explicitly create the Map with scala.collection.mutable.HashMap.

 

Monads


Monads are combinable parametrized container types which have support for higher-order functions. Remember higher-order functions are functions which receive functions as parameters and return functions as results. One of the most used functions in FP is Map. Map takes a function, applies it to each element in the container, and returns a new container.

Scala Map function in Scala REPL

We will see Map function in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> 
scala> val numbers = List(1,2,3,4,5,6)
numbers: List[Int] = List(1, 2, 3, 4, 5, 6)
scala> def doubleIt(i:Int):Double = i * 2
doubleIt: (i: Int)Double
scala> val doubled = numbers.map( doubleIt _ )
doubled: List[Double] = List(2.0, 4.0, 6.0, 8.0, 10.0, 12.0)
scala> val doubled = numbers.map( 2.0 * _ )
doubled: List[Int] = List(2.0, 4.0, 6.0, 8.0, 10.0, 12.0)
scala>

In the preceding code, we created a list of numbers containing 1,2,3,4,5, and 6. We also defined a Scala function called doubleIt, which receives an integer and multiplies it by 2.0 resulting in a double number. The map function calls doubleIt for each element in the List (1,2,3,4,5,6), and the result is a new container, a brand new List instance containing the new values.

Scala has some syntactical sugar which helps us to be more productive. For instance, you may realize that in the previous code, we also did - 2.0 * _. The underscore is a special operator for this specific case -- it means the current value is being iterated into the collection. Scala will create a function from this expression for us.

As you might have realized, map functions are pretty useful for lots of reasons: one reason is that you can do complex computations without using the for loop explicitly, and this makes your code functional. Secondly, we can use a map function to convert element types from one type to another. That's what we did in the previous code: we transformed a list of integers into a list of doubles. Look at the following:

scala> val one = Some(1)  
one: Some[Int] = Some(1)
scala> val oneString = one.map(_.toString)
oneString: Option[String] = Some(1)

The map function operates over several data structures and not only collections, as you can see in the previous code. You can use the map function on pretty much everything in Scala language.

The map function is great, but you can end up with nested structures. That's why, when we are working with Monads, we use a slightly different version of the map function called flatMap, which works in a very similar way to the map function, but returns the values in a flat form instead of nested values.

In order to have a monad, you need to have a method called flatMap. Other function languages such as Haskell call flatMap as bind, and use the operator >>=. The syntax changes with the language, but the concept is the same.

Monads can be built in different ways. In Scala, we need a single argument constructor which will work as a monad factory. Basically, the constructor receives one type, A, and returns Monad[A] or just M[A]. For instance, unit(A) for a List will be == List[A] and unit(A), where a is an Option == Option[A]. In Scala, you don't need to have unit; this is optional. To have a monad in Scala, you need to have map and flatMap implemented.

Working with Monads will make you write a little bit more code than before. However, you will get a way better API, which will be easier to reuse and your potential complexity will be managed, because you won't need to write a complex code full of if and for loops. The possibilities are expressed through the types, and the compiler can check it for you. Let us see a simple monad example in Scala language:

Option Monad in Scala

We will see option Monad in Scala as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val a:Option[Int] = Some(1)
a: Option[Int] = Some(1)
scala> a.get
res0: Int = 1
scala> val b:Option[Int] = None
b: Option[Int] = None
scala> b.get
java.util.NoSuchElementException: None.get
  at scala.None$.get(Option.scala:347)
  at scala.None$.get(Option.scala:345)
  ... 32 elided
scala> b.getOrElse(0)
res2: Int = 0
scala> a == b
res3: Boolean = false
scala> 

In Haskell, this also known as the Maybe monad. Option means optional value, because we are not 100% sure if the value will be present. In order to express a value, we use the Some type, and in order to express the lack of value, we use none. Option Monads are great, they make your code more explicit, because a method might receive or return an option, which means you are explicitly saying this could be null. However, this technique is not only more expressive but also safer, since you won't get a null pointer, because you have a container around the value. Although, if you call the method get in Option and it is none, you will get a NoSuchelementException. In order to fix this, you can use the method getOrElse, and you can supply a fallback value which will be used in the case of none. Alright, but you might be wondering where the flatMap method is. Don't worry, Scala implements this method for us into the Option abstraction, so you can  use it with no issues.

scala> val c = Some("one")
c: Some[String] = Some(one)
scala> c.flatMap( s => Some(s.toUpperCase) )
res6: Option[String] = Some(ONE)

The Scala REPL can perform autocomplete for you. If you type C + Tab, you will see all the available methods for the Some class. The map function is available for you to use, and as I said before, there is no unit function in Scala whatsoever. However, it is not wrong if you add in your APIs.

A list of all methods using the Scala REPL

Following are the list of all methods using the Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val c = Some("one")
c: Some[String] = Some(one)
scala> c.
++             count       foreach              iterator     productArity   seq         toBuffer             unzip          
++:            drop        genericBuilder       last         productElement size        toIndexedSeq         unzip3         
/:             dropRight   get                  lastOption   productIterator slice      toIterable           view           
:\             dropWhile   getOrElse            map          productPrefix  sliding     toIterator           withFilter     
WithFilter     equals      groupBy              max          
reduce         span        toLeft               x              
addString      exists      grouped              maxBy        
reduceLeft     splitAt     toList               zip           
aggregate      filter      hasDefiniteSize      min          reduceLeftOption stringPrefix   toMap           zipAll         
canEqual       filterNot   hashCode             minBy        reduceOption   sum         toRight              zipWithIndex   
collect        find        head                 mkString     reduceRight    tail        toSeq                
collectFirst   
flatMap        headOption  nonEmpty             reduceRightOption   tails          toSet       
companion            flatten     
init           orElse      repr                 take           
toStream       
contains    fold                 inits                orNull         sameElements takeRight           toString                       
copy           foldLeft    isDefined            par          
scan           takeWhile   toTraversable        
copyToArray    foldRight      isEmpty     partition            scanLeft            
to             toVector    
copyToBuffer         forall      isTraversableAgain product scanRight            toArray        
transpose                      
scala> c
 

Scala class, traits, and OO programming


As a hybrid post-functional language, Scala allows you to write OO code and create classes as well. Right now we will learn how to create classes and functions inside classes, and also how to work with traits, which are similar to Java interfaces in concept but way more powerful in practice.

A simple Scala class in Scala REPL

We will see a simple Scala class in Scala REPL as follows:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> class Calculator {
     |    def add(a: Int, b: Int): Int = a + b
     |    def multiply(n: Int, f: Int): Int = n * f
     | }
defined class Calculator
scala> 
scala> val c = new Calculator
c: Calculator = Calculator@380fb434
scala> c.add(1,2)
res0: Int = 3
scala> c.multiply(3,2)
res1: Int = 6
scala>

At first glance, the preceding code looks like Java. But let's add constructors, getters, and setters, and then you can see how much we can accomplish with just a few lines of code.

Scala plain old Java object in Scala REPL

Following is a Scala plain old Java object in Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> class Person(
     |   @scala.beans.BeanProperty var name:String = "",
     |   @scala.beans.BeanProperty var age:Int = 0
     | ){
     |    name = name.toUpperCase
     |    override def toString = "name: " + name + " age: " + age
     | }
defined class Person
scala> 
scala> val p  = new Person("Diego",31)
p: Person = name: DIEGO age: 31
scala> val p1 = new Person(age = 31, name = "Diego")
p1: Person = name: DIEGO age: 31
scala> p.getAge
res0: Int = 31
scala> p1.getName
res1: String = DIEGO
scala> 

Constructors in Scala are just lines of code. You might realize that we get the name variable, and apply a function to change the given name to upper case in the preceding example. If you want, you can put as many lines as you want, and you can perform as many computations as you wish.

On this same code, we perform method overriding as well, because we override the toString method. In Scala, in order to do an override, you need to use the override operator in front of the function definition.

We just wrote a Plain Old Java Object (POJO) with very few lines of code in Scala. Scala has a special annotation called @scala.beans.BeanProperty, which generates the getter and setter method for you. This is very useful, and saves lots of lines of code. However, the target needs to be public; you can't a apply BeanProperty annotation on top of a private var or val object.

Person class in Java

Following is a Person class in Java:

    package scalabook.javacode.chap1; 
 
    public class JavaPerson { 
   
      private String name; 
      private Integer age; 
   
      public JavaPerson() {} 
 
      public JavaPerson(String name, Integer age) { 
        super(); 
        this.name = name; 
        this.age = age; 
      } 
 
      public JavaPerson(String name) { 
        super(); 
        this.name = name; 
      } 
 
      public JavaPerson(Integer age) { 
        super(); 
        this.age = age; 
      } 
     
      public Integer getAge() { 
        return age; 
      } 
 
      public void setAge(Integer age) { 
        this.age = age; 
      } 
 
      public String getName() { 
        return name; 
      } 
 
      public void setName(String name) { 
        this.name = name; 
      } 
   
    } 
 

Traits and inheritance


It's possible to do inheritance in Scala as well. For such a task, you use the operator extend after the class definition. Scala just allows you to extend one class, just like Java. Java does not allow multiple inheritance like C++. However, Scala allows it by using the Mixing technique with traits. Scala traits are like Java interface, but you can also add concrete code, and you are allowed to have as many traits as you want in your code.

Scala inheritance code in Scala REPL

Following is a Scala inheritance code in Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> class Person(
     |   @scala.beans.BeanProperty var name:String = "",
     |   @scala.beans.BeanProperty var age:Int = 0
     | ){
     |    name = name.toUpperCase
     |    override def toString = "name: " + name + " age: " + age
     | }
defined class Person
scala> 
scala> class LowerCasePerson(name:String,age:Int) extends Person(name,age) {
     |    setName(name.toLowerCase)
     | }
defined class LowerCasePerson
scala> 
scala> val p  = new LowerCasePerson("DIEGO PACHECO",31)
p: LowerCasePerson = name: diego pacheco age: 31
scala> p.getName
res0: String = diego pacheco
scala> 

Scala does not make constructors inheritance like Java. So you need to rewrite the constructors and pass the values through a super class. All code inside the class will be the secondary constructor. All code inside parentheses () in the class definition will be the primary constructor. It's possible to have multiple constructors using the this operator. For this particular implementation, we changed the default behavior and added new constructor code in order to make the given name lower case, instead of the default uppercase defined by the Person superclass.

Scala traits sample code in Scala REPL

Following is a Scala traits sample code in Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> trait Car
defined trait Car
scala> 
scala> trait SportCar {
     |    val brand:String 
     |    def run():String = "Rghhhhh Rghhhhh Rghhhhh...."
     | }
defined trait SportCar
scala> 
scala> trait Printable {
     |    def printIt:Unit 
     | }
defined trait Printable
scala> 
scala> class BMW extends Car with SportCar with Printable{
     |    override val brand = "BMW"
     |    override def printIt:Unit = println(brand + " does " + run() )
     | }
defined class BMW
scala> 
scala> val x1 = new BMW
x1: BMW = BMW@22a71081
scala> x1.printIt
BMW does Rghhhhh Rghhhhh Rghhhhh....
scala>

In the preceding code, we created multiple traits. One is called Car, which is the mother trait. Traits support inheritance as well, and we have it with the SportCar trait which extends from the Car trait. The SportCar trait demands a variable called brand, and defines a concrete implementation of the function run. Finally, we have a class called BMW which extends from multiple traits -- this technique is called mixing.

Scala traits using variable mixing technique at Scala REPL

Following is a Scala traits using variable mixing technique at Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> trait SportCar {
     |    def run():String = "Rghhhhh Rghhhhh Rghhhhh...."
     | }
defined trait SportCar
scala> 
scala> val bmw = new Object with SportCar
bmw: SportCar = $anon$1@ed17bee
scala> bmw.run
res0: String = Rghhhhh Rghhhhh Rghhhhh....
scala>

Scala is a very powerful language indeed. It's possible to add traits to a variable at runtime. When you define a variable, you can use the with operator after the assignment. This is a very useful feature, because it makes it easier to make function composition. You can have multiple specialized traits and just add them in your variables as you need them.

Scala allows you to create the type alias as well, this is a very simple technique which will increase the readability of your code. It's just a simple alias.

Scala type alias sample in Scala REPL

Following is a Scala type alias sample in Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> type Email = String
defined type alias Email
scala> 
scala> val e = new Email("me@mail.com.br")
e: String = me@mail.com.br
scala>

When you are coding with Scala, it is highly recommended that you use the type alias and traits for everything, because that way you will get more advantages with your compiler, and you will avoid writing unnecessary code and unnecessary unit tests.

 

Case classes


We are not done yet in terms of the OO features in Scala; there is another very interesting way to work with classes in Scala: the so-called case classes. Case classes are great because you can have a class with way less number of lines of code and case classes can be part of a Pattern Matcher.

Scala case classes feature in Scala REPL

Following is a Scala case classes feature in Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> case class Person(name: String, age: Int)
defined class Person
scala> val p = Person("Diego",31)
p: Person = Person(Diego,31)
scala> val p2 = Person("Diego",32)
p2: Person = Person(Diego,32)
scala> p.name
res0: String = Diego
scala> p.age
res1: Int = 31
scala> p == p 
res2: Boolean = true
scala> p.toString
res3: String = Person(Diego,31)
scala> p.hashCode
res4: Int = 668670772
scala> p.equals(p2)
res5: Boolean = false
scala> p.equals(p)
res6: Boolean = true
scala>

This is the Scala way to work with classes. Because this is so much easier and compact, you pretty much create a class with one line of code, and you can have the equals and hashcode methods for free.

 

Pattern Matcher


When you code in Java, you can use a Switch statement. However, in Scala, we have a more powerful feature called Pattern Matcher, which is a kind of switch but on steroids.

Simple Pattern Matcher in Scala

Following is a Simple Pattern Matcher in Scala:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> def resolve(choice:Int):String = choice match {
     |     case 1 => "yes"
     |     case 0 => "no"
     |     case _ => throw new IllegalArgumentException("Valid arguments are: 0 or 1. Your arg is: 
           " + choice)
     | }
resolve: (choice: Int)String
scala> println(resolve(0))
no
scala> println(resolve(1))
yes
scala> try {
     |   println(resolve(33))
     | } catch{
     |   case e:Exception => println("Something Went Worng. EX: " + e)
     | }
Something Went Worng. EX: java.lang.IllegalArgumentException: Valid arguments are: 0 or 1. Your arg is: 33
scala>

Scala uses Pattern Matcher for error handling. Java does not have Pattern Matcher like Scala. It's similar to a switch statement; however, Pattern Matcher can be used in a method return statement as you can see in the preceding code. Scala developers can specify a special operator called _ (Underscore), which allows you to specify anything in the Pattern Matcher scope. This behavior is similar to else in an if conditional. However, in Scala, you can use _ in several places, and not only as the otherwise clause, like in Java switch.

Error handling in Scala is similar to error handling in Java. We use try...catch blocks. The main difference is that you have to use Pattern Matcher in Scala, which is great because it adds more flexibility to your code. Pattern Matcher in Scala can operate against many data structures like case classes, collections, integers, and strings.

The preceding code is pretty simple and straightforward. Next we will see a more complex and advanced code using the Scala Pattern Matcher feature.

Advanced pattern matcher in Scala REPL

Following is an Advanced Pattern Matcher using Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> def factorial(n:Int):Int = n match {
     |     case 0 => 1
     |     case n => n * factorial(n - 1)
     | }
factorial: (n: Int)Int
scala> 
scala> println(factorial(3))
6
scala> println(factorial(6))
720
scala> 

Pattern Matcher can be used in a very functional way. For instance, in the preceding code, we use the Pattern Matcher for recursion. There is no need to create a variable to store the result, we can put the Pattern Matcher straight to the function return, which is very convenient and saves lots of lines of code.

Advanced complex pattern matcher in Scala REPL

Following is an Advanced complex Pattern Matcher using Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> trait Color
defined trait Color
scala> case class Red(saturation: Int)   extends Color
defined class Red
scala> case class Green(saturation: Int) extends Color
defined class Green
scala> case class Blue(saturation: Int)  extends Color
defined class Blue
scala> def matcher(arg:Any): String = arg match {
     |   case "Scala"                            => "A Awesome Language"
     |   case x: Int                               => "An Int with value " + x
     |   case Red(100)                        => "Red sat 100"
     |   case Red(_)                            => "Any kind of RED sat"
     |   case Green(s) if s == 233       => "Green sat 233"
     |   case Green(s)                          => "Green sat " + s
     |   case c: Color                           => "Some Color: " + c
     |   case w: Any                            => "Whatever: " + w
     | }
matcher: (arg: Any)String
scala> println(matcher("Scala"))
A Awesome Language
scala> println(matcher(1))
An Int with value 1
scala> println(matcher(Red(100)))
Red sat 100
scala> println(matcher(Red(160)))
Any kind of RED sat
scala> println(matcher(Green(160)))
Green sat 160
scala> println(matcher(Green(233)))
Green sat 233
scala> println(matcher(Blue(111)))
Some Color: Blue(111)
scala> println(matcher(false))
Whatever: false
scala> println(matcher(new Object))
Whatever: java.lang.Object@b56c222
scala>

The Scala Pattern Matcher is really amazing. We just used an if statement in the middle of the Pattern Matcher, and also _ to specify a match for any kind of red value. We also used case classes in the middle of the Pattern Matcher expressions.

 

Partial functions


Partial functions are great for function composition. They can operate with case statements as we just learned from Pattern Matcher. Partial functions are great in the sense of function composition. They allow us to define a function in steps. Scala frameworks and libraries use this feature a lot to create abstractions and callback mechanisms. It's also possible to check if a partial function is being supplied or not.

Partial functions are predictable, because the caller can check beforehand if the value will be applied to the partial function or not. Partial function can be coded with or without case-like statements.

Simple Partial function in Scala REPL

Following is a simple Partial function using Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val positiveNumber = new PartialFunction[Int, Int] {
     |   def apply(n:Int) = n / n
     |   def isDefinedAt(n:Int) = n != 0
     | }
positiveNumber: PartialFunction[Int,Int] = <function1>
scala> 
scala> println( positiveNumber.isDefinedAt(6) )
true
scala> println( positiveNumber.isDefinedAt(0) )
false
scala> 
scala> println( positiveNumber(6) ) 
1
scala> println( positiveNumber(0) ) 
  java.lang.ArithmeticException: / by zero
  at $anon$1.apply$mcII$sp(<console>:12)
  ... 32 elided
scala>

Partial functions are Scala classes. They have some methods you need to provide, for instance, apply and isDefinedAt. The function isDefinedAt is used by the caller to check if the PartialFunction will accept and operate with the value supplied. The apply function will do the work when the PartialFunction is executed by Scala.

Scala PartialFunction without OO using case statements in Scala REPL

Following is a Scala PartialFunction without OO using case statements in Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val positiveNumber:PartialFunction[Int, Int]  =  {
     |   case n: Int if n != 0 => n / n
     | }
positiveNumber: PartialFunction[Int,Int] = <function1>
scala> 
scala> println( positiveNumber.isDefinedAt(6) )
true
scala> println( positiveNumber.isDefinedAt(0) )
false
scala> 
scala> println( positiveNumber(6) ) 
1
scala> println( positiveNumber(0) ) 
scala.MatchError: 0 (of class java.lang.Integer)
  at scala.PartialFunction$$anon$1.apply(PartialFunction.scala:253)
  at scala.PartialFunction$$anon$1.apply(PartialFunction.scala:251)
  at $anonfun$1.applyOrElse(<console>:11)
  at $anonfun$1.applyOrElse(<console>:11)
  at scala.runtime.AbstractPartialFunction$mcII$sp.apply$mcII$sp
  (AbstractPartialFunction.scala:36)
  ... 32 elided
scala>

Scala was a more fluent way to work with PartialFunction using the case statements. When you use the case statements, you don't need to supply the apply and isDefinedAt functions, since the Pattern Matcher takes care of that.

PartialFunction composition in Scala REPL

Following is a PartialFunction composition in Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> val even:PartialFunction[Int, String] = {
     |   case i if i%2 == 0 => "even"
     | }
even: PartialFunction[Int,String] = <function1>
scala> 
scala> val odd:PartialFunction[Int, String] = { case _ => "odd"}
odd: PartialFunction[Int,String] = <function1>
scala> 
scala> val evenOrOdd:(Int => String) = even orElse odd
evenOrOdd: Int => String = <function1>
scala> 
scala> println( evenOrOdd(1) == "odd"  )
true
scala> println( evenOrOdd(2) == "even" )
true
scala>

Scala allows us to compose as many PartialFunctions as we want. PartialFunction composition happens with the orElse function. In the preceding code, we defined an immutable variable called even, which verifies even numbers. Secondly, we created a second immutable variable called odd, which checks for odd numbers. Then we did the composition, and created a third PartialFunction called evenOrOdd with compose even and odd using the orElse operator.

 

Package objects


Scala has packages like Java. However, Scala packages are also objects, and you can have code inside a package. Java does not have the same power as Scala in terms of packages. If you add code to a package, it will be available to all classes and functions within that package.

package.scala

Your package.scala file should contain the following code

    package com.packait.scala.book 
 
    package object commons { 
   
      val PI = 3.1415926 
   
      object constraintsHolder { 
        val ODD = "Odd" 
        val EVEN = "Even" 
      } 
   
      def isOdd(n:Int):String  = if (n%2==0) constraintsHolder.ODD else 
      null   
 
      def isEven(n:Int):String = if (n%2!=0) constraintsHolder.EVEN 
      else null 
   
      def show(s:String) = println(s) 
   
    } 

This is the Scala package object. There is this special token called package object which you use to define common code to all classes, objects, and functions that are defined inside this package or sub-package. For this case, we define a value of PI as a constant and also one object holder containing the String values for Odd and Even. There are also three helper functions, which can and will be used by the classes inside this package.

MainApp.scala

Your MainApp.scala file should contain the following code

    package com.packait.scala.book.commons 
 
    object MainApp extends App { 
   
      show("PI is: " + PI) 
      show(constraintsHolder.getClass.toString()) 
   
      show( isOdd(2) ) 
      show( isOdd(6) ) 
 
      show( isEven(3) ) 
      show( isEven(7) ) 
   
    } 

As you can see in the preceding code, this new object is placed in the package: com.packait.scala.book.commons. Another interesting thing is the fact that we don't have any import statement here because of the package object feature. When you compile and run this program, you will see the following output:

PI is: 3.1415926
class com.packait.scala.book.commons.package$constraintsHolder$
Odd
Odd
Even
Even

Scala uses the Package object a great deal providing lots of shortcuts and convenience for all Scala developers. The following is the Scala package object definition:

    /*                     __                                               
    *\ 
    **     ________ ___   / /  ___     Scala API                            
    ** 
    **    / __/ __// _ | / /  / _ |    (c) 2003-2013, LAMP/EPFL             
    ** 
    **  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               
    ** 
    ** /____/\___/_/ |_/____/_/ | |                                         
    ** 
    **                          |/                                          
    ** 
    \*                                                                      
    */ 
 
    /** 
     * Core Scala types. They are always available without an explicit 
     import. 
     * @contentDiagram hideNodes "scala.Serializable" 
     */ 
    package object scala { 
      type Throwable = java.lang.Throwable 
      type Exception = java.lang.Exception 
      type Error     = java.lang.Error 
 
      type RuntimeException                = java.lang.RuntimeException 
      type NullPointerException            = 
      java.lang.NullPointerException 
      type ClassCastException              = 
      java.lang.ClassCastException 
      type IndexOutOfBoundsException       = 
      java.lang.IndexOutOfBoundsException 
      type ArrayIndexOutOfBoundsException  = 
      java.lang.ArrayIndexOutOfBoundsException 
      type StringIndexOutOfBoundsException = 
      java.lang.StringIndexOutOfBoundsException 
      type UnsupportedOperationException   = 
      java.lang.UnsupportedOperationException 
      type IllegalArgumentException        = 
      java.lang.IllegalArgumentException 
      type NoSuchElementException          = 
      java.util.NoSuchElementException 
      type NumberFormatException           = 
      java.lang.NumberFormatException 
      type AbstractMethodError             = 
      java.lang.AbstractMethodError 
      type InterruptedException            = 
      java.lang.InterruptedException 
 
      // A dummy used by the specialization annotation. 
      val AnyRef = new Specializable { 
        override def toString = "object AnyRef" 
      } 
 
      type TraversableOnce[+A] = scala.collection.TraversableOnce[A] 
 
      type Traversable[+A] = scala.collection.Traversable[A] 
      val Traversable = scala.collection.Traversable 
 
      type Iterable[+A] = scala.collection.Iterable[A] 
      val Iterable = scala.collection.Iterable 
 
      type Seq[+A] = scala.collection.Seq[A] 
      val Seq = scala.collection.Seq 
 
      type IndexedSeq[+A] = scala.collection.IndexedSeq[A] 
      val IndexedSeq = scala.collection.IndexedSeq 
 
      type Iterator[+A] = scala.collection.Iterator[A] 
      val Iterator = scala.collection.Iterator 
 
      type BufferedIterator[+A] = scala.collection.BufferedIterator[A] 
 
      type List[+A] = scala.collection.immutable.List[A] 
      val List = scala.collection.immutable.List 
 
      val Nil = scala.collection.immutable.Nil 
 
      type ::[A] = scala.collection.immutable.::[A] 
      val :: = scala.collection.immutable.:: 
 
      val +: = scala.collection.+: 
      val :+ = scala.collection.:+ 
     
      type Stream[+A] = scala.collection.immutable.Stream[A] 
      val Stream = scala.collection.immutable.Stream 
      val #:: = scala.collection.immutable.Stream.#:: 
 
      type Vector[+A] = scala.collection.immutable.Vector[A] 
      val Vector = scala.collection.immutable.Vector 
 
      type StringBuilder = scala.collection.mutable.StringBuilder 
      val StringBuilder = scala.collection.mutable.StringBuilder 
 
      type Range = scala.collection.immutable.Range 
      val Range = scala.collection.immutable.Range 
 
      // Numeric types which were moved into scala.math.* 
 
      type BigDecimal = scala.math.BigDecimal 
      val BigDecimal = scala.math.BigDecimal 
 
      type BigInt = scala.math.BigInt 
      val BigInt = scala.math.BigInt 
 
      type Equiv[T] = scala.math.Equiv[T] 
      val Equiv = scala.math.Equiv 
 
      type Fractional[T] = scala.math.Fractional[T] 
      val Fractional = scala.math.Fractional 
 
      type Integral[T] = scala.math.Integral[T] 
      val Integral = scala.math.Integral 
 
      type Numeric[T] = scala.math.Numeric[T] 
      val Numeric = scala.math.Numeric 
 
      type Ordered[T] = scala.math.Ordered[T] 
      val Ordered = scala.math.Ordered 
 
      type Ordering[T] = scala.math.Ordering[T] 
      val Ordering = scala.math.Ordering 
 
      type PartialOrdering[T] = scala.math.PartialOrdering[T] 
      type PartiallyOrdered[T] = scala.math.PartiallyOrdered[T] 
 
      type Either[+A, +B] = scala.util.Either[A, B] 
      val Either = scala.util.Either 
 
      type Left[+A, +B] = scala.util.Left[A, B] 
      val Left = scala.util.Left 
 
      type Right[+A, +B] = scala.util.Right[A, B] 
      val Right = scala.util.Right 
 
      // Annotations which we might move to annotation.* 
    /* 
      type SerialVersionUID = annotation.SerialVersionUID 
      type deprecated = annotation.deprecated 
      type deprecatedName = annotation.deprecatedName 
      type inline = annotation.inline 
      type native = annotation.native 
      type noinline = annotation.noinline 
      type remote = annotation.remote 
      type specialized = annotation.specialized 
      type transient = annotation.transient 
      type throws  = annotation.throws 
      type unchecked = annotation.unchecked.unchecked 
      type volatile = annotation.volatile 
      */ 
    } 
 

Functions


Like any great FP language, Scala has lots of built-in functions. These functions make our code more fluent and functional; now it's time to learn some of these functions:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> // Creates the numbers 1,2,3,4,5 and them multiply they by 2 and creates a new Vector
scala> println ((1 to 5).map(_*2))   
Vector(2, 4, 6, 8, 10)
scala> 
scala> // Creates 1,2,3 and sum them all with each orher and return the total
scala> println ( (1 to 3).reduceLeft(_+_) )
6
scala> 
scala> // Creates 1,2,3 and multiply each number by it self and return a Vector
scala> println ( (1 to 3).map( x=> x*x ) )
Vector(1, 4, 9)
scala> 
scala> // Creates numbers 1,2,3,4 ans 5 filter only Odd numbers them multiply them odds by 2 and return a Vector
scala> println ( (1 to 5) filter { _%2 == 0 } map { _*2 } )
Vector(4, 8)
scala> 
scala> // Creates a List with 1 to 5 and them print each element being multiplyed by 2
scala> List(1,2,3,4,5).foreach ( (i:Int) => println(i * 2 ) )
2
4
6
8
10
scala> 
scala> // Creates a List with 1 to 5 and then print each element being multiplied by 2
scala> List(1,2,3,4,5).foreach ( i => println(i * 2) )
2
4
6
8
10
scala> 
scala> // Drops 3 elements from the lists
scala> println( List(2,3,4,5,6).drop(3))
List(5, 6)
scala> println( List(2,3,4,5,6) drop 3 )
List(5, 6)
scala> 
scala> // Zip 2 lists into a single one: It will take 1 element of each list and create a pair List
scala> println(  List(1,2,3,4).zip( List(6,7,8) )) 
List((1,6), (2,7), (3,8))
scala> 
scala> // Take nested lists and create a single list with flat elements
scala> println( List(List(1, 2), List(3, 4)).flatten )
List(1, 2, 3, 4)
scala> 
scala> // Finds a person in a List by Age
scala> case class Person(age:Int,name:String)
defined class Person
scala> println( List(Person(31,"Diego"),Person(40,"Nilseu")).find( (p:Person) => p.age <= 33 ) )
Some(Person(31,Diego))
scala>
 

Partial application


In Scala, the underscore(_) means different things in different contexts. The underscore can be used to partially apply a function. It means a value will be supplied later. This feature is useful for function composition and allows you to reuse functions. Let's see some code.

Partial function in Scala REPL

Following is an example using Partial function in Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> def sum(a:Int,b:Int) = a+b
sum: (a: Int, b: Int)Int
scala> 
scala> val add6 = sum(6,_:Int)
add6: Int => Int = <function1>
scala> 
scala> println(add6(1))
7
scala>

In the preceding code, first, we define a function called sum, which takes two Int parameters and calculates a sum of these two parameters. Later, we define a function and hold it as a variable called add6. For the add6 function definition, we just call the sum function passing 6 and _. Scala will get the parameter passed through add6, and pass it through the sum function.

 

Curried functions


This feature is very popular in function languages like Haskell. Curried functions are similar to partial applications, because they allow some arguments to pass now and others later. However, they are a little bit different.

Curried functions - Scala REPL

Following is an example using curried function in Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> // Function Definition
scala> def sum(x:Int)(y:Int):Int = x+y
sum: (x: Int)(y: Int)Int
scala> 
scala> // Function call - Calling a curried function 
scala> sum(2)(3)
res0: Int = 5
scala> 
scala> // Doing partial with Curried functions
scala> val add3 = sum(3) _
add3: Int => Int = <function1>
scala> 
scala> // Supply the last argument now
scala> add3(3)
res1: Int = 6
scala>

For the preceding code, we create a curried function in the function definition. Scala allows us to transform regular/normal functions into curried functions. The following code shows the usage of the curried function.

Curried transformation in Scala REPL

Following is an example using curried transformation in Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> def normalSum(x:Int,y:Int):Int=x+y
normalSum: (x: Int, y: Int)Int
scala> 
scala> val curriedSum = (normalSum _).curried
curriedSum: Int => (Int => Int) = <function1>
scala> 
scala> val add3= curriedSum(3)
add3: Int => Int = <function1>
scala> 
scala> println(add3(3))
6
scala>
 

Operator overloading


Like C++, Scala permits operator overload. This feature is great for creating custom Domain Specific Languages (DSL), which can be useful to create better software abstractions or even internal or external APIs for developers, or for business people. You should use this feature with wisdom -- imagine if all frameworks decide to overload the same operators with implicits! You might run into trouble. Scala is a very flexible language compared to Java. However, you need to be careful, otherwise you could create code that's hard to maintain or even incompatible with other Scala applications, libraries, or functions.

Scala operator overloading in Scala REPL

Following is an example using Scala operator overloading in Scala REPL:

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> case class MyNumber(value:Int){
     | def +(that:MyNumber):MyNumber = new MyNumber(that.value + this.value)
     | def +(that:Int):MyNumber = new MyNumber(that + this.value)
     | }
defined class MyNumber
scala> val v = new MyNumber(5)
v: MyNumber = MyNumber(5)
scala> 
scala> println(v)
MyNumber(5)
scala> println(v + v)
MyNumber(10)
scala> println(v + new MyNumber(4))
MyNumber(9)
scala> println(v + 8)
MyNumber(13)
scala>

As you can see, we have two functions called +. One of this functions receives a MyNumber case class, and the other receives a Int value. You can use OO in Scala with regular classes and functions as well if you wish. We're also favoring immutability here because we always create a new instance of MyNumber when the operation + happens.

 

Implicits


Implicits allow you to do magic in Scala. With great power comes great responsibility. Implicits allow to you create very powerful DSL, but they also allow you to get crazy, so do it with wisdom. You are allowed to have implicit functions, classes, and objects. The Scala language and other core frameworks from the Scala ecosystem like Akka and PlayFramework use implicits many times.

Scala Implicits in SCALA REPL

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> implicit def transformStringtoInt(n:String) = n.toInt
warning: there was one feature warning; re-run with -feature for details
transformStringtoInt: (n: String)Int
scala> 
scala> val s:String = "123456"
s: String = 123456
scala> println(s)
123456
scala> 
scala> val i:Int = s
i: Int = 123456
scala> println(i)
123456
scala>

To use implicits, you need to use the keyword implicit before a function. Scala will implicitly call that function when it is appropriate. For this case, it will call to convert the String type to Int type as we can see.

Implicit Parameter at Scala REPL

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> implicit val yValue:Int = 6
yValue: Int = 6
scala> def sum(x:Int)(implicit yValue:Int) = x + yValue
sum: (x: Int)(implicit yValue: Int)Int
scala> val result = sum(10)
result: Int = 16
scala> println(result)
16
scala>

For this other case, given in the last code, we use an implicit parameter in the function sum. We also used a curried function here. We defined the implicit function first, and then called the sum function. This technique is good for externalized functions configuration and values you would let it hard code. It also saves lines of code, because you don't need to pass a parameter to all functions all the time, so it's quite handy.

 

Futures


Futures enable an efficient way to write parallel operations in a nonblocking IO fashion. Futures are placeholder objects for values that might not exist yet. Futures are composable, and they work with callbacks instead of traditional blocking code.

Simple Future code in Scala REPL

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> import concurrent.Future
import concurrent.Future
scala> import concurrent.ExecutionContext.Implicits.global
import concurrent.ExecutionContext.Implicits.global
scala> 
scala> val f: Future[String] = Future { "Hello world!" }
f: scala.concurrent.Future[String] = Success(Hello world!)
scala> 
scala> println("Result: " + f.value.get.get)
Result: Hello world!
scala> 
scala> println("Result: " + f)
Result: Success(Hello world!)
scala>

In order to work with futures in Scala, we have to import concurrent.Future. We also need an executor, which is a way to work with threads. Scala has a default set of execution services. You can tweak it if you like, however, for now we can just use the defaults; to do that, we just import concurrent.ExecutionContext.Implicits.global.

It's possible to retrieve the Future value. Scala has a very explicit API, which makes the developer's life easier, and also gives good samples for how we should code our own APIs. Future has a method called value, which returns Option[scala.util.Try[A]] where A is the generic type you are using for the future; for our case, it's a String A. Try is a different way to do a try...catch, and this is safer, because the caller knows beforehand that the code they are calling may fail. Try[Optional] means that Scala will try to run some code and the code may fail -- even if it does not fail, you might receive None or Some. This type of system makes everybody's lives better, because you can have Some or None as the Option return. Futures are a kind of callback. For our previous sample code, the result was obtained quite quickly, however, we often use futures to call external APIs, REST services, Microservices, SOAP Webservices, or any code that takes time to run and might not get completed. Futures also work with Pattern Matcher. Let's see another sample code.

A complete Future sample at Scala REPL

$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_77).
Type in expressions for evaluation. Or try :help.
scala> import concurrent.Future
import concurrent.Future
scala> import concurrent.ExecutionContext.Implicits.global
import concurrent.ExecutionContext.Implicits.global
scala> import scala.util.{Success, Failure}
import scala.util.{Success, Failure}
scala> def createFuture():Future[Int] = {
     | Future { 
     | val r = scala.util.Random
     | if (r.nextInt(100)%2==0) 0 else throw new RuntimeException("ODD numbers are not good here :( ")
     | }
     | }
createFuture: ()scala.concurrent.Future[Int]
scala> def evaluateFuture(f:Future[_]) {
     | f.onComplete {
     | case Success(i) => println(s"A Success $i ")
     | case Failure(e) => println(s"Something went wrong. Ex: ${e.getMessage}")
     | }
     | }
evaluateFuture: (f: scala.concurrent.Future[_])Unit
scala> evaluateFuture(createFuture)
scala> Something went wrong. Ex: ODD numbers are not good here :( 
evaluateFuture(createFuture)
A Success 0 
scala> evaluateFuture(createFuture)
Something went wrong. Ex: ODD numbers are not good here :( 
scala> evaluateFuture(createFuture)
Something went wrong. Ex: ODD numbers are not good here :( 
scala> evaluateFuture(createFuture)
A Success 0 
scala> evaluateFuture(createFuture)
A Success 0 
scala>

There is a function called createFuture, which creates Future[Int] each time you call it. In the preceding code, we use scala.util.Random to generate random numbers between 0 and 99. If the number is even, we return a 0, which means success. However, if the number is odd, we return a RuntimeException, which will mean a failure.

There is a second function called evaluateFuture, which receives any Future. We allow a result of any kind of generic parameterized type of function, because we used the magic underscore _. Then we apply Pattern Matcher with two case classes: Success and Failure. In both the cases, we just print on stdin. We also use another interesting and handy Scala feature called String interpolation. We need to we start the String with s before "". This allows us to use expressions with $ and ${} to evaluate any variable in the context. This is a different approach for String concatenation from what we have done so far. Later, we made 6 calls for the evaluteFuture function, passing a new Future each time, created by the function createFuture.

 

Reactive Programing and RxScala


Reactive programming is better, scalable, and a faster way to build applications. Reactive Programing can be done with OO languages, however, they make a lot of sense with FP languages. When FP is married to Reactive Programing, we get something called Functional Reactive Programing (FRP). Scala FRP can be used for many purposes like GUI, Robotics, and Music, because it gives you a better model to model time. Reactive programming is a new technique, which works with Streams(also known as Data Flows). Streams is a way to think and code applications in a way which can express data transformations and flow. The main idea is to propagate changes through a circuit or flow. Yes, we are talking about a new way to do async programming.

The main library for Reactive Programing is called Reactive Extensions (Rx) - http://reactivex.io/), originally built for .NET by Eric Meijer. It combines the best ideas from the Observer and Iterator Patterns, and FP. Rx has implementations for many languages like Scala, Java, Python, .NET, PHP, and others (https://github.com/ReactiveX). Coding with Rx is easy, and you can create Streams, combine with query-like operators, and also listen (subscribe) to any observable Streams to perform data transformations. Rx is used by many successful companies today like Netflix, GitHub, Microsoft, SoundCloud, Couchbase, Airbnb, Trello, and several others. In this book, we will use RxScala, which is the Scala implementation of the Reactive Streams.

The following table shows the main class/concepts you need to know in order to work with Rx.

Term / Class

Concept

Observable

Create async composable Streams from sources.

Observer

A callback function type.

Subscription

The bound between the Subscriber and the Observable. Receives notifications from Observables.

Reactive Streams is also the name of a common specification trying to consolidate and standardize the reactive stream processing, There are several implementations such as RxJava/RxScala, Reactor, Akka, Slick, and Vert.x. You can find more at https://github.com/reactive-streams/reactive-streams-jvm.

Back to the Observables -- we can perform all kinds of operations with observables. For instance, we can filter, select, aggregate, compose, perform time-based operations, and apply backpressure. There are two big wins with Observables instead of callbacks. First of all, Observables are not opinionated about how low-level I/O and threading happens, and secondly, when you are doing complex code, callbacks tend to be nested, and that is when things get ugly and hard to read. Observables have a simple way to do composition thanks to FP.

Observables push values to consumers whenever values are available, which is great because then the values can arrive in sync or async fashion. Rx provides a series of collection operators to do all sorts of data transformations you may need. Let's see some code now. We will use RxScala version 0.26.1, which is compatible with RxJava version 1.1.1+. RxScala is just a wrapper for RxJava (Created by Netflix). Why not use RxJava straight? Because the syntax won't be pleasant; with RxScala, we can have a fluent Scala experience. RxJava is great, however, Java syntax for this is not pleasant - as Scala is, in fact, pretty ugly.

Simple Observables Scala with RxScala

package scalabook.rx.chap1 
 
import rx.lang.scala.Observable 
import scala.concurrent.duration._ 
 
object SimpleRX extends App { 
   
  val o = Observable. 
            interval(100 millis). 
            take(5)             
             
  o.subscribe( x => println(s"Got it: $x") )             
  Thread.sleep(1000)           
             
  Observable. 
      just(1, 2, 3, 4). 
      reduce(_+_). 
      subscribe( r => println(s"Sum 1,2,3,4 is $r in a Rx Way")) 
   
} 

If you run this preceding Scala program, you will see the following output:

Simple Observables Scala with RxScala - Execution in the console

Got it: 0 
Got it: 1 
Got it: 2 
Got it: 3 
Got it: 4 
Sum 1,2,3,4 is 10 in a Rx Way 

If you try to run this code in the Scala REPL, it will fail, because we need the RxScala and RxJava dependencies. For this, we will need SBT and dependency management. Do not worry, we will cover how to work with SBT in our Scala application in the next chapter.

Going back to the observables, we need to import the Scala Observable. Make sure you get it from the Scala package, because if you get the Java one, you will have issues: in the very first part of the code, we will get numbers starting from 0 each 100 milliseconds, and this code would run forever. To avoid this, we use the take function to put a limit into the collection, so we will get the first five values. Then, later, we subscribe to the observer, and when data is ready, our code will run. For the first sample, it's pretty easy, we are just printing the values we have got. There is a thread sleep in this program, otherwise, the program would terminate, and you would not see any value on the console.

The second part of the code does something more interesting. First of all, it creates an Observable from a static list of values, which are 1,2,3, and 4. We apply a reduce function into the elements, which will sum all the elements with each other, and then we subscribe and print the result.

Complex Scala with RxScala Observables

package scalabook.rx.chap1 
 
import rx.lang.scala.Observable 
 
object ComplexRxScala extends App { 
   
  Observable. 
      just(1,2,3,4,5,6,7,8,9,10).       // 1,2,3,4,5,6,7,8,9,10 
      filter( x => x%2==0).             // 2,4,6,8,10 
      take(2).                          // 2,4 
      reduce(_+_).                      // 6 
      subscribe( r => println(s"#1 $r")) 
   
   val o1 = Observable. 
            just(1,2,3,4,5,6,7,8,9,10).  // 1,2,3,4,5,6,7,8,9,10 
            filter( x => x%2==0).        // 2, 4, 6, 8, 10 
            take(3).                     // 2, 4 ,6     
            map( n => n * n)             // 4, 16, 36 
   
   val o2 = Observable.                  
            just(1,2,3,4,5,6,7,8,9,10). // 1,2,3,4,5,6,7,8,9,10  
            filter( x => x%2!=0).       // 1, 3, 5, 7, 9    
            take(3).                    // 1, 3, 5 
            map( n => n * n)            // 1, 9, 25 
            
   val o3 = o1. 
           merge(o2).                  // 2,16, 36, 1, 9, 25 
           subscribe( r => println(s"#2 $r")) 
       
} 

The preceding first part of the code creates an Observable with numbers from 1 to 10, and then applies a filter function, which will get only the even numbers. It then reduces them, calculates their sum, and lastly, prints the solution. You can visualize it as depicted in the following image:

For the second part of the code, we create two different observables. The first one is with even numbers and the second one is with odd numbers. These two observables are decoupled from each other; you can control as many observables you want. Later on, the code uses a merge function to join these two observables into a third and new observable containing the content of the first and second observables.

Merging 2 Observables

There are many functions and options, and you can see the whole list at http://rxmarbles.com/ and https://github.com/ReactiveX/RxScala. For the sake of simplicity, for now, we are just working with numbers. Later, we will use this to do more advance compositions including database calls and external web services calls.

 

Summary


In this chapter, we learned the basic concepts of FP, Reactive Programing, and the Scala language. We learned about the basic constructs of the Scala language and Functional Programming, functions, collections, and OO in Scala, and concurrent programming with Futures.

Next, we will see how to use SBT to build Scala projects. We will learn how to compile and run Scala applications using SBT.

About the Author
  • Diego Pacheco

    Diego Pacheco is an experienced software architect and DevOps practitioner with over 10 years of solid experience. He has led architecture teams using open-source solutions such as Java, Scala, AWS Cloud, Akka, Cassandra, Redis, ActiveMQ, NetflixOSS Stack: Simian Army, RxJava, Karyon, Eureka, and Ribbon on Big Customers in Brazil, London, Barcelona, India, and the USA. Diego has a passion for functional programming and is currently working as a Software Architect/Agile Coach with Scala, Akka, and NetflixOSS.

    During his free time, he enjoys playing wicked tunes on his guitar, gaming, and blogging. You can check out his blog http://diego-pacheco.blogspot.in/

    Browse publications by this author
Latest Reviews (1 reviews total)
enough said enough said enough said enough said enough said
Building Applications with Scala
Unlock this book and the full library FREE for 7 days
Start now