 2/20

Functions and structures

• while loops
• do while loops
• for loops
• functions
• anonymous functions

In this section we will look at control structures and functions. If you are using the Scala REPL, you could copy/paste complex structures directly into the shell by first issuing the command :paste and once you are done Ctrl-D.

Here is an example

scala> :paste
// Entering paste mode (ctrl-D to finish)

def divNums (num1: Int, num2: Int)  = try
{
num1 / num2
} catch {
case ex: java.lang.ArithmeticException => "Nope! Can't do!"
} finally {
// some cleanup
}

println(divNums(1,0))
<<< this is where you issue Ctrl+D
// Exiting paste mode, now interpreting.

Nope! Can't do!
divNums: (num1: Int, num2: Int)Any

scala>

Run the examples below in your Scala shell and see the results.

While loops

var i = 0; while (i <= 10) { println(i); i += 1 }

Do while loops

var i = 0; do { println(i); i += 1} while (i <= 10)

For loops

Regular for loops

for (i <- 1 to 10) println(i) // inclusive 10
for (i <- 1 until 10) println(i) // exclusive 10

Using for loop to traverse a string.

val letters = "ABCDEFGHJKLMNOPQRSTUVXYWZ"

for (i <- 0 until letters.length) {
print(s"\${letters(i)} ")
}

Reading from a list

val lst = List(1, 2, 3, 4, 5)

for (i <- lst){
println(s"A list with the element \$i "))
}

A double for loop

for (i <- 1 to 5; j <- 6 to 10) println(s"\$i, \$j")

A for comprehension loop with a boolean condition

{for(x <- 1 to 10 if x % 2 == 1) yield x * 10 } foreach(println)

Functions

A function will be defined by the def keyword, it may take one, more or no parameters.
For non recursive functions, the return type doesn't need to be specified.

def fact(n: Int) = {
var r = 1
for (i <- 1 to n) r = r * i
r // return keyword is not needed
}

However, for recursive functions, the return type needs to be specified, otherwise you will be greeted with recursive method fact needs result type error.

def fact(n: Int): BigInt = if (n <= 0) 1 else n * fact(n - 1)

The function below has one default argument, which can be omitted when the function is called. While the other arguments, if given in the correct order, they don't need to be called by name:

def getCalc(num1: Int, num2: Int, num3: Int = 2): Int = {
num1 + num2 * num3
}

Calling the function without the positional argument and with the default values

scala> getCalc(1,3)
// res: Int = 7

Calling the function without the positional argument and changing the default values

scala> getCalc(1, 3, 4)
// res: Int = 13

Calling the function with the positional arguments and default values

scala> getCalc(num2 = 1,num1 = 3)
// res: Int = 5

You can have a function with variable number of arguments

def summation(args: Int*) = {
var res = 0
for (arg <- args) res += arg
res
}

summation(1,2,6,9,3)
// res: Int = 21

The equivalent of a static function or method in Java it is called a procedure in Scala and the return type is a Unit.

def triangle(i: Int): Unit = {
if(i < 0) return
for (x <- 0 to i) {
println("x" * x)
}
}

Anonymous functions

Below are some scalaesque examples of anonymous functions.

// following statements are all equivalent
import scala.language.postfixOps

> (1 to 5) .map(2 *)
> (1 to 5) .map(2 * _)
> (1 to 5) .map(x => 2 * x)

res3: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)

Pipeline anonymous functions

> (1 to 10).filter(_ % 2 == 0).map(2 *)
res12: scala.collection.immutable.IndexedSeq[Int] = Vector(4, 8, 12, 16, 20)

[+] Scala series
• Small steps to Scala 1/20 - the basiscs

• Disclaimer: This is by no means an original work it is merely meant to serve as a compilation of thoughts, code snippets and teachings from different sources.