Scala - the basics

Marcel L├╝thi
Departement of Mathematics and Computer Science

Why Scala?

why-scala

Python

Advantages

  • Easy to learn
  • Elegant
  • Ubiquitous

Disadvantages

  • Brittle for large programs
  • Slow

Solution: Write core in C++

Python with C++ core

Advantages

  • Easy to use (through Python) and fast
  • Can scale to huge programs

Disadvantage

  • Difficult to program / maintain (C++)
  • Difficult to deploy (C++)
  • Serious researchers need to learn 2 languages
  • C++ alone more complicated than Scala. Combination makes things worse!

Scala - A scalable language

Good to experiment - possible to scale

  • Modern
    • but with good ecosystem
  • Elegant - clean concepts
  • Open source
  • Platform independent
  • Interoperable with Java
  • Statically typed
  • Fusion of object-oriented and functional

Scala

  • Academic roots

    • built on well founded theoretical concepts
  • Concepts not difficult but need to be learned

Learning concepts makes you a better programmer

Example Scala program


object Example {

    abstract class Tree
    case class Branch(left: Tree, right: Tree) extends Tree
    case class Leaf(x: Int) extends Tree

    val tree1 = Branch(Branch(Leaf(1), Leaf(2)), Branch(Leaf(3), Leaf(4)))

    def sumLeaves(t: Tree): Int = t match {
        case Branch(l, r) => sumLeaves(l) + sumLeaves(r)
        case Leaf(x) => x
    }

    println("sum of leafs=" + sumLeaves(tree1))       
}

Basics of Scala

Slides are loosely based on

Expressions

  • Expressions are program text
  • Expressions evaluate to values
  • Expressions have a type
In [ ]:
(5 + 3) * 8
In [ ]:
List(1,2,3).toString

Values

  • Expressions can be named using val
In [ ]:
val myCalculation = (5 + 3) * 8
In [ ]:
val myExtendedCalculation = myCalculation * 10

Types

  • Every expression has a type
In [ ]:
val a : Int = (5 + 3) * 8
In [ ]:
val b = ((5 + 3 ) * 8).toString
In [ ]:
val c : String = (5 + 3 ) * 8

Expression, types and values

expression-types-values

Blocks

  • Sequence of expressions
  • Last line is result of block
    • Block is itself expression
In [ ]:
{
    val x = 1 + 1
    x + 1
}

Blocks

  • Blocks are expressions - can be named
In [ ]:
val result = {
    val x = 1 + 1
    x + 1
}

Blocks

  • Can be placed everywhere an expression is required
In [ ]:
println( { val x = 1 + 1
           x + 1} )

Functions

  • Expressions that take parameter

functions

Functions

In [ ]:
(x : Int) => x + 3
  • Function body can be a block (as block is expression)
In [ ]:
(x : Int) => {
    val y = 1
    x + y
}

Functions

  • Functions are expressions, hence values
In [ ]:
val f = (x : Int) => {
    val y = 1
    x + y
} 

f(3)

Try it out

  • Create some simple expressions
  • Try out blocks
  • Create a function
  • Create a function that takes a function as a parameter

Methods

methods

Similar to functions, but with special syntax

In [ ]:
def add(x : Int, y : Int) = x + y

add(5, 3)

Classes

  • Similar to Java
    • Main difference: Argument list as constructor
In [ ]:
class Greeter(prefix : String, suffix : String) {
    
    print("hello world")
    
    
    def greet(name : String) : Unit = println(prefix +"-" + name +"-" +suffix)
}
In [ ]:
val greeter = new Greeter("probabilistic", "modelling")
greeter.greet("shape")

Case classes

  • Special classes for organizing data
    • Ensure proper equality
    • Do not need new keyword
    • constructor arguments are public by default
In [ ]:
case class Point(x : Double, y : Double)
In [ ]:
val p = Point(3, 5)

Objects

  • Whenever only a single instance is needed
  • Often associated to class with same name
    • Called companion object
class PositiveNumber(num : Int) { 
    // some methods
}

object PositiveNumber {
    val MaxValue : Int = java.lang.Integer.MAX_VALUE
    val MinValue : Int = 0
}

Parametric types

Types in Scala can be parametric

case class Pair[A, B](first : A, second : B)

Usage:

val pair1 = Pair(3, 5.0) 
val pair2 : Pair[String, Int] = Pair("abc", 5)
  • Types are inferred automatically when possible

Parametric types

Methods can be parametric

def first[A, B](pair : Pair[A, B]) : A = pair.first

val pair = Pair(3, 5.0)
first(pair)

Pattern matching

  • Generalizes switch/case statement from java
expression match { 
    case pattern1 => expression1 
    case pattern2 => expression2 
    // ...
}

Pattern matching

In [ ]:
val res = 2 match { 
    case 1 => "one" 
    case 2 => "two" 
    case _ => 5
}
In [ ]:
def matchTest2(x: Any): Int = x match { 
    case 1 => 1
    case "two" => 2 
    case y: Int => y
    case _ => 99
} 
matchTest2(55)

Next time - Scala, the simple parts

How these concepts fit together