Intro to Scala for Java Programmers: Part 1

The goal of this article series is to introduce Scala to people who know how to program in Java, and want a fast introduction to the Scala language in order to be capable of reading (simple) Scala code and of course, understanding it. In part 1 we focus on the most basic constructs like variable declarations, control structures, function definitions.

Variable declaration

In Scala there are two ways to declare a variable, with the keywords val and var.

For example, we can declare the variable toto0 like this:

val toto0 = 1

Or like this:

var toto1 = 1

In both cases we are declaring a variable of type Int. The difference between both declarations is that the val declaration declares a constant, i.e. the variable cannot be reassigned after its initial definition. On the other hand, the var variable can be reassigned a new value.

If you come from Java, the same declarations in Java would be like this:

// val toto0 = 1
final int toto0 = 1;
// var toto1 = 1
int toto0 = 1;

Typing in Scala

If you come from Java and other strongly typed languages, you might have noticed that Scala variable declarations lack a type. However, there is actually a type, but it is inferred by the compiler. Scala has type inference, this is, the compiler will try to infer the type of the variable and you don’t have to type it (most of the time.

Of course, there are times when the compiler cannot infer the type or sometimes you just want to have the type explicitly to make things clear to the readers of the code. For this purpose Scala has the : (colon). The colon is pronounced “is of type”. Let us look at some examples:

// we can define our same variable but specifying the type
val toto0: Int = 1

The aforementioned code is read as “constant toto0 is of type integer and has assigned value 1”.

Contrary to some other languages once a variable has a certain type, it stays with that type for the rest of its existence.

Predefined Operations and Types

Scala comes with a standard library containing common types and operations. To simplify, we present the different Scala types together with their Java counterparts:

Java Scala Scala Example Possible values
byte Byte val b: Byte = 1 $-2^7$ to $2^7 - 1$
short Short val s: Short = 1 $-2^{15}$ to $2^{15} - 1$
char Char val c = 'c' All Unicode characters.
int Int val i = 1 $-2^{31}$ to $2^{31} - 1$
long Long val l = 1L $-2^{63}$ to $2^{63} - 1$
float Float val f = 1.5f All IEEE 754 32 bit single precision floating point values
double Double val d = 1.5 All IEEE 754 64 bit double precision floating point values
boolean Boolean val b = true $\lbrace$ true, false $\rbrace$
void Unit val u = () $\lbrace$ () $\rbrace$

Table 1: List of Scala Value Types

The one type that deserves an explanation is the Unit type. The unit type only has one possible value, written as (). It is used as the return type for subroutines that do not return a value. For example, when we call println to print a line in Scala it returns a unit type, we can see an example here:

val r = println("Hello!")

By using the unit type, Scala guarantees that all subroutines are functions, i.e. they always return a value.

Exercise

Create an integer variable, a long variable, and then a new variable that contains the result of adding both previous variables. What is the type of the new variable?

Basic Operations

The standard numeric data types supported by Scala that we previously shown support the usual arithmetic operations that we expect them to. Scala supports all the following operations between numeric types (byte, short, int, long, float, double): +, -, *, /, and %. The % is the modulus operator, used as follows a % b and returns the remainder of dividing a by b, for example 10 % 3 is equal to 1.

The following relational operators ==, != (not equal), >, >= (greater or equal), <, <= (less or equal) are also supported by Scala with their usual semantics for numeric types. Contrary to Java, the == operator actually calls the equals method when applied to two objects that are not numerical. To have the same semantics as Java == and != we need to use the eq and ne operators respectively.

For Boolean data types Scala supports the classical logical operators && (logical and), || (logical or), and ! (logical negation) that return a Boolean value depending on the result of the comparison.

In addition to that, in the same style as Java, Scala supports the assignment and operation combination, that allows to apply and operation and the assign the value to a variable in one compact operation. The operators supported are += (add and assign), -= (subtract and assign), *= (multiply and assign), /= and assign, /= (divide and assign), and %= (modulus and assign). F

var x = 5
x += 2
// x = 7
var y = 10
y %= 3
// y = 1

Control Structures

Scala provides the standard control structures usually found in other languages. Here we focus on the ones that are shared with Java, highlighting Scala’s particularities.

The fundamental building block for control is the well known if-else statement. In Scala, the particularity of the if-else statement is that it is a function, i.e. it returns a value. Let us consider the following example

val a = 5
if (a > 1) 4 else 1

The statement above returns an actual value, the value 4 (since a > 1). This means that, in Scala we can assign an if-block to a variable or use it where we would expect some value. For example:

val a = 5
val b = if (a > 1) 4 else 1
// b = 4

The question that you might be asking is “What happens when there is no else?”, what is returned then? The answer is simple, the unit value. Let us consider the following code:

val x = if (false) 5
// x: AnyVal = ()

As you can see, after the execution variable x contains the value (), but the type of x is AnyVal, a type that is the super type of all types listed in Table 1. Hence, we can see that the compiler inferred the return type of the if expression as AnyVal.

Scala also support classic loop instructions such as while, do-while, and for. The while and do-while work exactly as expected. Let us consider the following loop:

var x = 3
while (x > 0) {
  println(x)
  x=x-1
}

This loop will print all numbers from 3 to 1. We can do the exact same loop using the do-while construct:

var x = 3
do {
  println(x)
  x -= 1
} while (x > 0)

Following the Scala convention, both of these operations return a value, the unit value ().

Function Definitions

The definition of a function in Scala is done with the def keyword, followed by the function name, the list of arguments, the = sign and the actual function body. A simple Scala function looks like this:

def add(x: Int, y: Int) = x + y

Exercise

Implement the function compare that compares to integers x and y, and returns -1 if x < y, 0 if they are equal, 1 if x > y.

Here we can find the colon that we already met in the last section. It is there to inform the compiler that x and y are parameters of type Int. Of course, we can do more complex functions using Scala. For example, we can have a block of statements with variable definitions, function calls, and everything that you can have in other common programming languages, the syntax for that is the following:

def complexFct(x: Int, y: Int) = {
  val operand1 = x
  val operand2 = y
  operand1 + operand2
}

You might have noticed that the function does not have a return type, like you would have in other languages. Like variable definitions, function return types are inferred by the compiler, thus you (usually) don’t need to tell the compiler the return type of a function. A notable exception for this are recursive functions, which always require the programmer to properly specify the return type, let us look at an example for the factorial function $n! = n \cdot (n - 1) \cdots 2 \cdot 1$. This function is easily defined in Scala as:

def fact(n: Int): Int = if (n > 1) n * fact(n - 1) else 1

Conclusion

We have seen the basics of the Scala language. Using the knowledge we have we can write simple programs by using scalar types, simple arithmetic operations and function definitions.

References

  • For the ranges of the different data types in Scala you can check out the lexical syntax specification of the language.
comments powered by Disqus