Welcome to the Scala tutorial. We will cover the Scala in two-part blog series. In this part, we will learn the following topics
- Scala Features
- Variables and Methods
- Condition and Loops
- Variables and Type Inference
- Classes and Objects
For better understanding, do hands-on with this tutorial. We’ve made this post in such a way that the reader will find easy to follow the tutorial with hands-on.
Scala Features
Scala is a modern multi-paradigm programming language designed to express common programming patterns in a concise, elegant, and type-safe way.
It is a statically typed language. Which means it does type checking at compile-time as opposed to run-time. Let me give you an example to better understand this concept.
When we deploy jobs which will run for hours in production, we do not want to discover midway that the code has unexpected runtime errors. With Scala, you can be sure that your code will not give you unexpected errors while running in production.
Since Scala is statically typed we get performance and speed over dynamic languages.
How is Scala different than Java?
Unlike Java, in Scala, we do not have to write quite as much code to perform simple tasks and its syntax is very similar to other data-centric languages. You could say that Scala is the modified version of Java with less boilerplate code.
Let’s look back at the origin of the Scala.
In 1990, Martin Odersky, creator of Scala, made Java better by introducing generics in javac – the Java Compiler.
In 2001, he decided to create even better Java and in 2003, there was the first experimental release of Scala. To prove the correctness of Scala, scala2.0 was compiled in Scala itself in 2005.
In 2011, corporate stewardship was brought to ensure that the language was enterprise-ready at all times.
Scala compiler compiles Scala code into Java bytecode. The resulting bytecode is executed by a JVM – the Java virtual machine.
Since Scala and Java have a common runtime, Java libraries may be used directly in Scala code and vice versa.
The best way to learn a programming language is by writing code. So, Please do not just read this tutorial. Instead, work with it.
Let’s get started. Login to Cloudxlab.
Scala provides a nice interactive console which would give us result instantaneously. It is also called REPL – read-evaluate-print-loop. To start Scala console or REPL, type Scala after logging into Cloudxlab web console.
Variables and Methods
In the previous step, we started Scala successfully. Let’s continue from there. You can use this Scala console a very simple calculator as well.
So, if you type 2+4 it would compute the sum.
scala> 2 + 4 res0: Int = 6
You can see that it has given the answer as 6 and also defined a variable called res0 which contains the result. The data type of res0 is Int which means integer.
To see the value of a variable you can simply type the name of the variable and it would print the value contained in the variable.
scala> res0 res1: Int = 6
You can see that it has displayed the value of res0.
We can also define our own variables by using var. So, if I say var x = 10, it would create x having value as 10.
scala> var x = 10 x: Int = 10
Also, we can use x in other calculation. For example, var y = x * 4 So, this first multiplies x by 4 and then it assigns the result to y. You can see that the value of y is 40.
scala> var y = x * 4 y: Int = 40
We have used addition and multiplication operators so far. Similarly, we also have name operators called methods. These methods take inputs via arguments and optionally returns the result.
For example, print displays the value on the screen. Let’s see.
if you type: print(“Hello, World”)
It prints the “Hello, World” on the screen.
Here print method takes a string or text as input by the way of the first argument. Also, notice that we define a string by enclosing something in double quotes.
Also, note that we define a single character by enclosing it in single quotes.
scala> var a = 'h' a: Char = h
You can see that we defined a variable “a” having character “h” as the value.
This print is an inbuilt method. There are some other libraries of methods which are provided by Scala. For example, math library.
Let import all functions from maths library by typing: import math._
scala> import math._ import math._
Now we can use functions such as sqrt() for computing square root of a value.
scala> sqrt(25) res3: Double = 5.0
You can see the square root of 25 is 5.
Now, let’s practice the variable and methods by computing simple interest.
Let’s define our principal amount, rate, and duration.
scala> var principal = 10 principal: Int = 10 scala> var rate = 10 rate: Int = 10 scala> var duration = 4 duration: Int = 4
We will be using the simple interest formula, i.e. principal * rate * duration / 100
scala> var interest = principal * rate * duration / 100 interest: Int = 4
So, you can see the interest is 4.
Now, we change the principal amount to 100. And re-execute the formula.
scala> principal = 100 principal: Int = 100 scala> var interest = principal * rate * duration / 100 interest: Int = 40
What if you need to calculate interest for multiple values of principal or rate or duration? It is indeed tiring to write the formula every time we change the value.
We can also define our own methods so that we don’t need to write the same code again and again.
Let’s define a method called simpleInterest in the following way:
scala> def simpleInterest(principal: Int, rate: Double, duration: Int): Double = { var interest = principal * rate * duration / 100; return interest; }
Our first argument is principal which is an integer, the second argument is rate which is double, and the third argument is the duration (years) which is an integer.
And the return type is of type double.
We start the body of the method after the open curly bracket. Inside this function, we are going to return the simpleinterest which is principal * rate * duration divided by 100.
Then we close the curly brackets to mark the end of the method definition.
Let’s try to call the method that we have just defined by providing principal as 700, rate of interest is 7, and duration as 4 years.
scala> simpleInterest(700, 7, 4) res0: Double = 196.0
You can see that the interest is 196.
So, we have created our own interest computing machine which we can use as many times as we want.
Condition and Loops
In programming, the first step of logic is a conditional statement such as if-else.
Let’s do a hands-on on variables. Login to CloudxLab and type scala to launch the Scala shell.
Let’s redefine our function and put a conditional check in our method of simple interest. If someone enters negative principal that is less than 0, we print “Wrong principal” and return 0 as result.
def simpleInterest(principal: Int, rate: Double, duration: Int): Double = { if (principal < 0) { println("Wrong principal"); return 0; } var interest = principal * rate * duration / 100; return interest; }
Everything between curly brackets of if block will be executed if the condition “principal less than 0” is true. If the condition is false, the statement outside the if block will be executed and our interest is calculated and returned as usual.
Let’s check by calling our method with principal amount as negative 100.
scala> simpleInterest(-100, 7, 4) wrong principal res1: Double = 0.0
You can see that it has printed “wrong principal” and the interest is 0.
Sometimes you may need to operate on the list of things. For that, Scala provides a List data type.
Let define our list having numbers 4, 9, and 8 and store in the variable a.
scala> var a = List(4, 9, 8) a: List[Int] = List(4,9,8)
We can operate on a list in a variety of ways. One of the most common ways is to go through every element using a for loop.
Now we write a for loop that will print the numbers in the list.
scala> for (x <- a) { println(x) }
It is always best to refer (x <- a) as ‘x’ in ‘a’, where ‘a’ is a list and ‘x’ is the current element. We are printing x i.e. each value of a.
While Loop
There is another way of executing a logic multiple times – A while loop.
A while loop has two parts – one condition and another body. The body keeps getting executed as long as the condition is true. If the condition remains true forever, it would keep executing the body forever.
Let’s print all numbers less than 15. So, we define a variable x with value 15.
scala> var x = 15; x: Int = 15 scala> while(x > 0) { println(x); x = x - 1 }
Inside while loop we have two statements – one for printing value of x and another decreases the value of x by 1.
This loop will stop as soon as the value of x is zero.
scala> var x = 9; x: Int = 9 scala> while(x > 0) { println(x); x = x - 1 } 9 8 7 6 5 4 3 2 1
As you can see we have printed all the number less than 9 but greater than 0.
Variable and Type Inference
Variables are nothing but reserved memory locations to store values. This means that when we create a variable, the compiler allocates a memory based on its data type.
There are two types of variables in Scala – Mutable and Immutable.
Mutable variables are defined using var keyword and their value can be changed. Immutable variables are defined using val keyword and their value can not be changed once assigned.
Let’s define an immutable variable x of integer type with value 8. Type val x: Int = 8. Now try changing the value of x to 9.
scala> val x: Int = 8 x: Int = 8 scala> x = 9 <console> error: reassignment to val x = 9 ^
We have got an error. As discussed we can not change the value of an immutable variable.
Let’s define a mutable variable “y” of integer type with value 7. Type var y: Int = 7. Now try changing the value of “y” to 9.
scala> var y: Int = 7 y: Int = 7 scala> y = 9 y: Int = 9
We can see that its value is now 9.
Let’s understand why do we need immutable variables?
In large systems, we do not want to be in a situation where a variable’s value changes unexpectedly as this may lead to unpredictable results.
In the case of Threads, APIs, functions, and classes, we may not want some of the variables to change.
In these scenarios, we define the variables as immutable variables.
In Scala, we can define the variables without specifying their datatype. The Scala compiler can understand the type of the variable based on the value assigned to it. This is called variable type inference.
Let us define a variable x and assign it a value “hi”. Type var x = “hi” in the Scala shell. You will see that Scala determines the type of variable x as “String”.
But, we should always try to explicitly define a type of variable to ensure that the code is compiled faster and to avoid any unpredictable results.
Classes and Objects
What is a class? A class is a way of creating your own data type. A class is a way of representing a type of value inside the system.
For example, we can create a data type that represents a customers using a class. A customer would have states like first name, last name, age, address and contact number.
A customer class might represent behaviors for how these states can be transformed. For example how to change a customer’s address or name. These behaviors are called methods. A class is not concrete until it has been instantiated using a “new” keyword.
scala> class Person(val fname: String, val lname: String, val anage: Int) { val firstname: String = fname; val lastname: String = lname; val age = anage; }
As you can see on the screen, we’ve defined a person class and it has three parameters – first name of string type, last name of string type and age of integer type.
We’ve assigned these parameters to immutable class variables. Let’s create an instance of the class.
scala> val obj = new Person("Robin", "Gill", 42)
We’ve created an instance of Person class with firstname as Robin, lastname as Gill and age as 42.
We can access class variables from the instance by the following way.
scala> obj.firstname res0: String = Robin scala> obj.age res1: Int = 42
Let’s define a class method to get the full name of the person.
scala> class Person(val fname: String, val lname: String, val anage: Int) { val firstname: String = fname; val lastname: String = lname; val age = anage; def getFullName():String = { return firstname + " " + lastname; } }
As you can see on the screen, we have defined a method getFullName. This method concatenates firstname and lastname and returns a full name which is of string type.
Objects in Scala are Singleton. A singleton is a class which can only have one instance at any point in time.
Methods and values that aren’t associated with individual instances of a class belong in singleton objects.
A singleton class can be directly accessed via its name. We can create a singleton class using the keyword object.
Let’s create an object Hello which has a method message which returns a string “hello”.
scala> object Hello { def message(): String = { return "Hello!"; } } scala> Hello.message res0: String = Hello!
We can access the method message without instantiating the instance of “Hello”. This is because Hello is a singleton object and it is already instantiated for us when we try to call the message method.
Objects are useful in defining constants and utility methods as they are not related to any specific instance of the class. Utility methods take parameters and return values based on a calculation and transformation
Next Steps on Scala Tutorial?
If you like the post, please share it with your friends and family who you think might find it useful. Also, we will cover the remaining topics in part 2 of the Scala series. Meanwhile, you can go through our Linux series here.