Scala

This is a page on the Scala programming language.

How to declare variables

val vs. var

a val is like a final variable in java which makes it immutable:

val someText = "Hi hi hi hi"
//Not allowed
someText = "ho ho ho"

a var is mutable hence the name var (variable):

var someMoreText = "tihi tihi"
//Allowed
someMoreText = "rofl"

In Scala it’s not necessary to explicitly declare the type of the val/var when it’s the declared. Scala will infer the type on compile time, which leeds to less verbose code compared to Java.

You can however define the type if you wish to:

val: java.lang.String someText = "Hi hi hi hi"

How to define functions

Functions are were the magic happens.

def plus(x: Int, y: Int): Int = {
  x + y
}
println(plus(1, 2))

A function starts with the keyword def followed by its name then followed by a list of parameters, the parameter list is then followed by a colon, then the return type followed by a equal sign. The function declaration is then followed by the function body where the function is implemented.

In Java the return keyword should be used to specify what is returned from a method, but in Scala this is not necessary since a Scala function always returns the last expression in the function body, here being the x + y.

Function parameters has to have there type defined as the Scala compiler can’t infer function parameters.

The functions return type is only mandatory if the function is recursive, which is not the case for our plus function. So it could be written like this:

def plus(x: Int, y: Int): = {
  x + y
}
println(plus(1, 2))

The function body can be omitted if a function contains no more than one line of code. Our plus function could therefore be re-written like this:

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

Scripts

To create a script just create a file containing your Scala code then save it as a .scala file and run it using the scala command.

A simple script that reads one arg and prints it:

println(args(0))

Now save the script and run it.

Loops

Scala supports the standard loops like while and for.

The while loop is as expected and here is a code snippet that counts to 10 and prints it.

var i = 0

while(i <= 10){
  if(i == 10){
    print(i)
    i += 1
  }
  else{
    print(i + ", ")
    i += 1
  }
}

foreach

The foreach function takes a function literal which gets passed the argument from each iteration of the List

Here are some examples using foreach on a simple string

//Infers the type of the arg passed to foreach
"Hello world".foreach(arg => print(arg))

//Specify the type of the argument passed to foreach
"Hello world".foreach((arg: Char) => print(arg))

//Shorthand that can only be used when there is only one argument (arg) and one statement ( print() )
"Hello world".foreach(print)

for loop

//Example of using the old trusty for construct
for(arg <- "Hello world")
  print(arg)

//Using ranges
for(i <- 0 to 2)
  print("hep")

for(i <- 0 until 2)
  print("hep")

//Filtering
val names = List("Pete", "Susan", "Bob", "Chris")

for(name <- names if name.contains("s")) {
  println(name)
}

Holding your Objects

Scala contains a diverse collection of object containers.

Let’s start with the array:

// Create a new array containing String with a size of 3
val greetStrings = new Array[String](3)

// More verbose
// val greetStrings: Array[String] = new Array[String](3)

// Less verbose - infers array to only take strings and size to be 3
//val greetStrings = Array("Hello from Melmac", "Hello from Mars", "Hello from Betelgeuse")

greetStrings(0) = "Hello from Melmac"
greetStrings(1) = "Hello from Mars"
greetStrings(2) = "Hello from Betelgeuse"

// Wups - trying to put an Int into an array of Strings!
//greetStrings(1) = 1

// Won't work, array is not big enough..
//greetStrings(3) = "Hep hep!"

for(i <- 0 to 2)
  println(greetStrings(i))

The next one up is the scala.List. Scala List implementation is special in the sense that it’s immutable and are therefore safe to share.

val oneTwoThree = List(1, 2, 3)
val fourFiveSix = List(4, 5, 6)

// Define a new list using :: to add 1,2,3 to an empty List (Nil)
//val oneTwoThree = 1 :: 2 :: 3 ::Nil

// Method for concatenation of two Lists
val newList = oneTwoThree ::: fourFiveSix

// Method for adding an element in the beginning of a List - “cons”
val newList2 = 0 :: newList

// Add 1 to each of the elements in newList2 and return that List
val addOne = newList2.map(i => i + 1)

// Print out all even-numbers in newList2
newList2.filter(i => (i % 2 == 0) ).foreach(arg => print(arg + " "))

// Count the number of evennumbers in List newList2
println("Number of evennumbers: " + newList2.count(_ % 2 == 0)

Exception handling

Scala is implemented in a similar fasion to all the main programming languages using the try, catch, finally construct.

try{
  val number = 10

  val someValue =
    if(number == 1)
      "yes"
    else
      throw new IllegalArgumentException("Value should be 1")

  println(someValue)
}
catch {
  case e: IllegalArgumentException => {
    println("IllegalArgumentException was thrown: " + e.getMessage)
  }
  case e: IndexOutOfBoundsException => {
    println("IndexOutOfBoundsException was thrown: " + e.getMessage)
  }
  case e: IOException => {
    println("IOException was thrown: " + e.getMessage)
  }
}

Classes and Objects

Scala is an object oriented language so classes and objects are a vital part of the toolkit. Let’s start by looking at how to define classes in scala.

A simple class is defined by the class keyword followed by it’s name and a set of curly brackets to contain the body of the class

class SimpleClass {
  // Class body
}

val myNewClass = new SimpleClass()

Adding a constructor to your class is simple. Just add () to the end of the class name and add the desired arguments. Arguments declared as var are mutable, were args declared as val are immutable. Args declared with neither val nor var is private.

class SimpleClass(a: String,  val b: String, var c: String) {}
val myNewClass = new SimpleClass("tihihih", "lololo", "hahahaha")

//myNewClass.a can only be accessed in the class itself
//myNewClass.a

//myNewClass.b can be retrieved but not updated
println(myNewClass.b)
//myNewClass.b = "are you really immutable"

//myNewClass.c can be retrieved and updated
println(myNewClass.c)
myNewClass.c = "you are not immutable"
println(myNewClass.c)

Classes are not that interesting without behaviour

//Define a class
//arguments with neither val nor var is private to the class
//arguments with val can only be retrieved (get)
//arguments with var can be retrieved and updated (get/set)
class SomeClass(a: String,  val b: String, var c: String) {

  //Create a function that returns a String
  def someFunction() :String = {
    "hello from some function"
  }

  //define a function that takes a function literal
  def someOtherFunction(op: (String) => Unit){
    op("hello from some other function")
  }
}
//Companion object - good place to put factory methods
object SomeClass {
  def createSomeClass(a: String,  b: String, c: String)  = new SomeClass(a, b, c)
}

//Create an instance of the new class
val someClass = SomeClass.createSomeClass("tihih", "hohoh", "lololol")

//someClassa can only be accessed in the class itself
//someClass.a

//someClassb can be retrieved but not updated
println(someClass.b)
//someClass.b = "are you really immutable"

//someClass.c can be retrieved and updated
println(someClass.c)
someClass.c = "you are not immutable"
println(someClass.c)

someClass.someOtherFunction(println(_))

//Easy way to create an immutable DTO/value object that takes a string as it's only constructor arg
class DTO(val a: String)

val dto = new DTO("Immutable")

println(dto.a)

Leave a comment