Scala Introduction Constantine Nosovsky
Agenda  Motivation  Imperative vs Functional  What is Scala?  Scala syntax intro  Case classes, tail recursion  Putting it all together  Pure functional theory implementation  Collections  Advanced topics  Resources
Motivation  Top “Scala” queries for the past 12 months Google trends (http://www.google.com/trends/)
Imperative vs Functional  Imperative – Mutable variables – Assignments – Control structures (if-else, loops, break, continue, return) – Sequence of instructions executed one-by-one – Strong correspondence to the computer components
Imperative vs Functional  Functional – Immutable variables – Functions are treated as a first-class data types – Production, consumption and composition of functions – Corresponds to math theory where data, operations and relationships are described, e.g. Matrix theory
Functional programming benefits  Better programming abstraction: combine complex operations by composing primitives  Looser coupling: no side effects only input and output parameters => better contract conformation  Better scalability: immutable (therefore thread-safe) objects
What is Scala?  Designed by Martin Odersky, 2003  Multi-paradigm: Functional and Imperative  Object oriented – Even primitive types are objects – Singleton objects instead of static methods and fields  Platform: JVM, LLVM  Compatible with Java
Scala syntax intro: value declaration  Static strong inferred typing val a: Int = 5 is similar to val a = 5 // type will be inferred
Scala syntax intro: final  Subsequent assignment are not allowed val a: Int = 5 a = 10 // error: reassignment to val var a: Int = 5 a = 10 // OK for var, avoid using vars!
Scala syntax intro: method, expression  Expressions instead of statements def abs(x: Int): Int = if (x >= 0) x else –x Or even val result = { if(f(x)) x else -x } * 2
Scala syntax intro: high-order functions  Functions might be passed as parameters def map(xs: List[Int], m: Int => Int): List[Int] = if(xs.isEmpty) List() else List(m(xs.head)) ++ map(xs.tail, m) // pass function as a parameter def square(x: Int) = x * x map(List(1, 2, 3), square) map(List(1, 2, 3), x => x * x)
Scala syntax intro: classes class Class { def method = println("Class") } new Class().method // singleton object instead of static method object Singleton { def method = println("Singleton") } Singleton.method
Scala syntax intro: traits  Trait is similar to interface, but may contain implementation trait Drawable { def draw() } trait Cowboy extends Drawable { override def draw() = println("Bang!") } trait Artist extends Drawable { override def draw() = println("A painting") } class CowboyArtist extends Cowboy with Artist // "A painting" will be used
Scala syntax intro: operators  Easy to build DSL class Complex { def add(y: Complex) = ??? def +(y: Complex) = add(y) def unary_- = ??? } val x = new Complex(); val y = new Complex() x.add(y); x add y; x.+(y); x + y // equivalent -x // unary operator
Case classes and pattern matching // class applicable for pattern-matching case class Complex(r: Int, i: Int) // implicitly generated companion factory class val v = Complex(1, 2); val v2 = Complex(2, 3) // match object value and constructor arguments v match { case Complex(r, _) => println("Real " + r) case null => println("No value") }
Recursion  Recursion is often used for list processing def sum(xs: List[Int]): Int = if(xs.isEmpty) 0 else xs.head + sum(xs.tail) Problem: list of 1 million elements causes stack overflow
Tail recursion  If a function calls itself as its last action, the function’s stack frame can be reused def sum(xs: List[Int]): Int = { // will be compiled to a loop in byte code @tailrec def loop(acc: Int, xs: List[Int]): Int = if(xs.isEmpty) 0 else loop(acc + xs.head, xs.tail) loop(0, xs) }
Putting it all together  No mutable data sharing problem – Variables are final by nature – Classes are designed to be immutable  Easy composition – Everything is an expression returning result – Mixing functions, methods and operators – No side effects, i/o parameters only – Closure  Advanced type safety – Inferred: automatic deduction of the data type  OOP – Singleton classes instead of static methods/fields – Primitive types are objects as well – Traits for abstraction and multiple inheritance – Case classes and pattern matching
Pure functional theory implementation  Build a Set theory  Operations – Check whether an element belongs to a set – Union, Intersection, Difference – Filter set elements with a predicate  Sets are immutable, each modification produces a new set  Functional way: no data structures, only rules
Pure functional theory implementation // Set is a function checking element presence type Set = Int => Boolean def contains(s: Set, elem: Int): Boolean = s(elem) // Returns the set of the one given element def singletonSet(elem: Int): Set = (x: Int) => x == elem
Pure functional theory implementation  Union, intersect, diff operations def union(s: Set, t: Set): Set = (x: Int) => s(x) || t(x) def intersect(s: Set, t: Set): Set = (x: Int) => s(x) && t(x) def diff(s: Set, t: Set): Set = (x: Int) => s(x) && !t(x)
Pure functional theory implementation  Filter elements // Returns the subset of s for which p holds def filter(s: Set, p: Int => Boolean): Set = intersect(s, p)
Pure functional theory implementation  Usage example val oddNumbers = (x: Int) => x % 2 == 1 val range = (x: Int) => x > 0 && x < 100 filter(range, oddNumbers)
Collections  Mostly immutable data structures  Modifications will create a new instance  Optimized for language structures – Functional way of processing and construction – Pattern matching – For expressions
Collections: List  scala.collection.immutable.List  Linked list implementation  Case class, has a factory val list = List(1, 2, 3)  Prepending element will create a new list (shallow copy) val newList = 0 :: list
Collections: List  Methods head and tail used for one by one processing def contains(l: List[Int], e: Int): Boolean = if(l.isEmpty) false else l.head == e || contains(l.tail, e)  Applicable for pattern matching def contains(l: List[Int], e: Int): Boolean = l match { case List() => false case head :: tail => head == e || contains(tail, e) }
Collections: Vector  Faster access by index than linked list  Supports almost similar operations  Hierarchical data structure – Array of 32 elements – After all elements are filled becomes an array of 32 references to arrays of elements – Then next level, again and again references references … references elements elements … elements
Collections: common methods  exists, forall – contains by predicate  zip, unzip – transform two collection into a single one chaining corresponding items into a tuple  map, flatMap – apply transformation to each element  to[List, Map, Set, Stream]  sum, product, max, min
Advanced topics  OOP in Scala: – Traits – Generics, bounding – Subtyping (Any, Nothing) – Polymorphism  Language structures – For expressions – Lazy evaluation – Currying – Implicit parameters – Tuples  Concurrency  Scala frameworks: akka, play
Resources  Coursera class by Martin Odersky https://class.coursera.org/progfun-004  Scala API documentation http://www.scala-lang.org/api/current  Programming in Scala Martin Odersky, Lex Spoon, Bill Venners. 2nd ed. Artima 2010  Scala tutorial by Twitter http://twitter.github.io/scala_school/

Scala Introduction

  • 1.
  • 2.
    Agenda  Motivation  Imperative vs Functional  What is Scala?  Scala syntax intro  Case classes, tail recursion  Putting it all together  Pure functional theory implementation  Collections  Advanced topics  Resources
  • 3.
    Motivation  Top“Scala” queries for the past 12 months Google trends (http://www.google.com/trends/)
  • 4.
    Imperative vs Functional  Imperative – Mutable variables – Assignments – Control structures (if-else, loops, break, continue, return) – Sequence of instructions executed one-by-one – Strong correspondence to the computer components
  • 5.
    Imperative vs Functional  Functional – Immutable variables – Functions are treated as a first-class data types – Production, consumption and composition of functions – Corresponds to math theory where data, operations and relationships are described, e.g. Matrix theory
  • 6.
    Functional programming benefits  Better programming abstraction: combine complex operations by composing primitives  Looser coupling: no side effects only input and output parameters => better contract conformation  Better scalability: immutable (therefore thread-safe) objects
  • 7.
    What is Scala?  Designed by Martin Odersky, 2003  Multi-paradigm: Functional and Imperative  Object oriented – Even primitive types are objects – Singleton objects instead of static methods and fields  Platform: JVM, LLVM  Compatible with Java
  • 8.
    Scala syntax intro:value declaration  Static strong inferred typing val a: Int = 5 is similar to val a = 5 // type will be inferred
  • 9.
    Scala syntax intro:final  Subsequent assignment are not allowed val a: Int = 5 a = 10 // error: reassignment to val var a: Int = 5 a = 10 // OK for var, avoid using vars!
  • 10.
    Scala syntax intro:method, expression  Expressions instead of statements def abs(x: Int): Int = if (x >= 0) x else –x Or even val result = { if(f(x)) x else -x } * 2
  • 11.
    Scala syntax intro:high-order functions  Functions might be passed as parameters def map(xs: List[Int], m: Int => Int): List[Int] = if(xs.isEmpty) List() else List(m(xs.head)) ++ map(xs.tail, m) // pass function as a parameter def square(x: Int) = x * x map(List(1, 2, 3), square) map(List(1, 2, 3), x => x * x)
  • 12.
    Scala syntax intro:classes class Class { def method = println("Class") } new Class().method // singleton object instead of static method object Singleton { def method = println("Singleton") } Singleton.method
  • 13.
    Scala syntax intro:traits  Trait is similar to interface, but may contain implementation trait Drawable { def draw() } trait Cowboy extends Drawable { override def draw() = println("Bang!") } trait Artist extends Drawable { override def draw() = println("A painting") } class CowboyArtist extends Cowboy with Artist // "A painting" will be used
  • 14.
    Scala syntax intro:operators  Easy to build DSL class Complex { def add(y: Complex) = ??? def +(y: Complex) = add(y) def unary_- = ??? } val x = new Complex(); val y = new Complex() x.add(y); x add y; x.+(y); x + y // equivalent -x // unary operator
  • 15.
    Case classes andpattern matching // class applicable for pattern-matching case class Complex(r: Int, i: Int) // implicitly generated companion factory class val v = Complex(1, 2); val v2 = Complex(2, 3) // match object value and constructor arguments v match { case Complex(r, _) => println("Real " + r) case null => println("No value") }
  • 16.
    Recursion  Recursionis often used for list processing def sum(xs: List[Int]): Int = if(xs.isEmpty) 0 else xs.head + sum(xs.tail) Problem: list of 1 million elements causes stack overflow
  • 17.
    Tail recursion If a function calls itself as its last action, the function’s stack frame can be reused def sum(xs: List[Int]): Int = { // will be compiled to a loop in byte code @tailrec def loop(acc: Int, xs: List[Int]): Int = if(xs.isEmpty) 0 else loop(acc + xs.head, xs.tail) loop(0, xs) }
  • 18.
    Putting it alltogether  No mutable data sharing problem – Variables are final by nature – Classes are designed to be immutable  Easy composition – Everything is an expression returning result – Mixing functions, methods and operators – No side effects, i/o parameters only – Closure  Advanced type safety – Inferred: automatic deduction of the data type  OOP – Singleton classes instead of static methods/fields – Primitive types are objects as well – Traits for abstraction and multiple inheritance – Case classes and pattern matching
  • 19.
    Pure functional theoryimplementation  Build a Set theory  Operations – Check whether an element belongs to a set – Union, Intersection, Difference – Filter set elements with a predicate  Sets are immutable, each modification produces a new set  Functional way: no data structures, only rules
  • 20.
    Pure functional theoryimplementation // Set is a function checking element presence type Set = Int => Boolean def contains(s: Set, elem: Int): Boolean = s(elem) // Returns the set of the one given element def singletonSet(elem: Int): Set = (x: Int) => x == elem
  • 21.
    Pure functional theoryimplementation  Union, intersect, diff operations def union(s: Set, t: Set): Set = (x: Int) => s(x) || t(x) def intersect(s: Set, t: Set): Set = (x: Int) => s(x) && t(x) def diff(s: Set, t: Set): Set = (x: Int) => s(x) && !t(x)
  • 22.
    Pure functional theoryimplementation  Filter elements // Returns the subset of s for which p holds def filter(s: Set, p: Int => Boolean): Set = intersect(s, p)
  • 23.
    Pure functional theoryimplementation  Usage example val oddNumbers = (x: Int) => x % 2 == 1 val range = (x: Int) => x > 0 && x < 100 filter(range, oddNumbers)
  • 24.
    Collections  Mostlyimmutable data structures  Modifications will create a new instance  Optimized for language structures – Functional way of processing and construction – Pattern matching – For expressions
  • 25.
    Collections: List scala.collection.immutable.List  Linked list implementation  Case class, has a factory val list = List(1, 2, 3)  Prepending element will create a new list (shallow copy) val newList = 0 :: list
  • 26.
    Collections: List Methods head and tail used for one by one processing def contains(l: List[Int], e: Int): Boolean = if(l.isEmpty) false else l.head == e || contains(l.tail, e)  Applicable for pattern matching def contains(l: List[Int], e: Int): Boolean = l match { case List() => false case head :: tail => head == e || contains(tail, e) }
  • 27.
    Collections: Vector Faster access by index than linked list  Supports almost similar operations  Hierarchical data structure – Array of 32 elements – After all elements are filled becomes an array of 32 references to arrays of elements – Then next level, again and again references references … references elements elements … elements
  • 28.
    Collections: common methods  exists, forall – contains by predicate  zip, unzip – transform two collection into a single one chaining corresponding items into a tuple  map, flatMap – apply transformation to each element  to[List, Map, Set, Stream]  sum, product, max, min
  • 29.
    Advanced topics OOP in Scala: – Traits – Generics, bounding – Subtyping (Any, Nothing) – Polymorphism  Language structures – For expressions – Lazy evaluation – Currying – Implicit parameters – Tuples  Concurrency  Scala frameworks: akka, play
  • 30.
    Resources  Courseraclass by Martin Odersky https://class.coursera.org/progfun-004  Scala API documentation http://www.scala-lang.org/api/current  Programming in Scala Martin Odersky, Lex Spoon, Bill Venners. 2nd ed. Artima 2010  Scala tutorial by Twitter http://twitter.github.io/scala_school/