107
Introduction to Scala Aleksandar Prokopec EPFL

Scala presentation by Aleksandar Prokopec

Embed Size (px)

Citation preview

Page 1: Scala presentation by Aleksandar Prokopec

Introduction to Scala

Aleksandar Prokopec

EPFL

Page 2: Scala presentation by Aleksandar Prokopec
Page 3: Scala presentation by Aleksandar Prokopec

Pragmatic

Since

2003

runs on the JVM

Seamless Javainteroperability

Statically typedProduction

ready

Martin Odersky

Hybrid

Page 4: Scala presentation by Aleksandar Prokopec

Statically typed

Page 5: Scala presentation by Aleksandar Prokopec

runs on the JVM

Page 6: Scala presentation by Aleksandar Prokopec

Scala programs are fast.

Page 7: Scala presentation by Aleksandar Prokopec

OOP + FP

Page 8: Scala presentation by Aleksandar Prokopec

“I can honestly say if someone had shown me the Programming Scala book by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I'd probably have never created Groovy.“

James Strachan, creator of Groovy

Page 9: Scala presentation by Aleksandar Prokopec

“If I were to pick a language to use today other than Java, it would be Scala.”

James Gosling

Page 10: Scala presentation by Aleksandar Prokopec

Pragmatic

Page 11: Scala presentation by Aleksandar Prokopec

Scala is lightweight.

Page 12: Scala presentation by Aleksandar Prokopec

println(“Hello world!”)

Page 13: Scala presentation by Aleksandar Prokopec

scala> println(“Hello world!”)Hello world!

REPLevaluating expressions on the fly

Page 14: Scala presentation by Aleksandar Prokopec

object MyApp extends App { println(“Hello world!”)}

Compiled version

Page 15: Scala presentation by Aleksandar Prokopec

object MyApp extends App { println(“Hello world!”)}

Singleton objectsno more static methods

Page 16: Scala presentation by Aleksandar Prokopec

object MyApp { def main(args: Array[String]) { println(“Hello world!”) }}

Declaring methods

Page 17: Scala presentation by Aleksandar Prokopec

object MyApp { def main(args: Array[String]) { var user: String = args(0) println(“Hello, ”+user+“!”) }}

Declaring variables

Page 18: Scala presentation by Aleksandar Prokopec

object MyApp { def main(args: Array[String]) { val user: String = args(0) println(“Hello, ”+user+“!”) }}

Declaring valuesprevents accidental changes

Page 19: Scala presentation by Aleksandar Prokopec

object MyApp { def main(args: Array[String]) { val user = args(0) println(“Hello, ”+user+“!”) }}

Local type inferenceless… “typing”

Page 20: Scala presentation by Aleksandar Prokopec

class StringArrayFactory { def create: Array[String] = { val array: Array[String] = Array[String](“1”, “2”, “3”) array }}

Local type inferenceless… “typing”

Page 21: Scala presentation by Aleksandar Prokopec

class StringArrayFactory { def create = { val array = Array(“1”, “2”, “3”) array }}

Local type inferenceless… “typing”

Page 22: Scala presentation by Aleksandar Prokopec

// Scalaclass Person( var name: String, var age: Int)

Declaring classes…concisely

// Javapublic class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; }}

Page 23: Scala presentation by Aleksandar Prokopec

Scala is object-oriented.

Page 24: Scala presentation by Aleksandar Prokopec

object Foo { val b = new ArrayBuffer[Any]}

Object-orientedeverything’s an object

Page 25: Scala presentation by Aleksandar Prokopec

Object-orientedeverything’s an object

Any

AnyRefAnyVal

String

Boolean

CharInt

Page 26: Scala presentation by Aleksandar Prokopec

object Foo { val b = new ArrayBuffer[Any] b += 1 b += 1.toString b += Foo println(b)}

Object-orientedeverything’s an object

Page 27: Scala presentation by Aleksandar Prokopec

1 + 21.+(2)

Array(1, 2, 3) ++ Array(4, 5, 6)Array(1, 2, 3).++(Array(4, 5, 6))

1 :: List(2, 3)List(2, 3).::(1)

Operator overloadingoperators are methods

Page 28: Scala presentation by Aleksandar Prokopec

trait Iterator[T] { def next(): T def hasNext: Boolean}

Declaring traitstraits are like interfaces

Page 29: Scala presentation by Aleksandar Prokopec

trait Iterator[T] { def next(): T def hasNext: Boolean def printAll() = while (hasNext) println(next())}

Declaring traitstraits are rich

Page 30: Scala presentation by Aleksandar Prokopec

trait Animal

Multiple inheritancetraits are composable

Page 31: Scala presentation by Aleksandar Prokopec

trait Animaltrait Mammal extends Animal { def think() = println(“hm...”)}

Multiple inheritancetraits are composable

Page 32: Scala presentation by Aleksandar Prokopec

trait Animaltrait Mammal extends Animal { def think() = println(“hm...”)}trait Bird extends Animal { def layEgg() = System.createEgg()}

Multiple inheritancetraits are composable

Page 33: Scala presentation by Aleksandar Prokopec
Page 34: Scala presentation by Aleksandar Prokopec

trait Animaltrait Mammal extends Animal { def think() = println(“hm...”)}trait Bird extends Animal { def layEgg() = System.createEgg()}class Platypus extends Bird with Mammal

Mixin compositiontraits are composable

Page 35: Scala presentation by Aleksandar Prokopec

trait Animaltrait Reptile extends Animal { def layInTheSun: Unit = {}}class Dog(name: String) extends Mammal

new Dog(“Nera”) with Reptile

Dynamic mixin composition…or composition “on the fly”

Page 36: Scala presentation by Aleksandar Prokopec

Cake pattern

Page 37: Scala presentation by Aleksandar Prokopec

trait Logging { def log(msg: String)}

trait AnsweringMachine { self: Logging with DAO with Protocol => log(“Initializing.”) ...}

Self-typesto express requirements

Page 38: Scala presentation by Aleksandar Prokopec

trait ConsoleLogging { def log(msg: String) = println(msg)}

class LocalAnsweringMachineextends AnsweringMachine with ConsoleLogging with H2DAO with JabberProtocol

Cake patternlayers above layers

Page 39: Scala presentation by Aleksandar Prokopec

Scala is functional.

Page 40: Scala presentation by Aleksandar Prokopec

(x: Int) => x + 1

First class functions

Page 41: Scala presentation by Aleksandar Prokopec

val doub: Int => Int = (x: Int) => x * 2

doub(1) 2

First class functionsfunctions are objects too

Page 42: Scala presentation by Aleksandar Prokopec

val doub = (x: Int) => x * 2

List(1, 2, 3).map(doub) List(2, 4, 6)

First class functionsas higher order parameters

Page 43: Scala presentation by Aleksandar Prokopec

List[Int](1, 2, 3).map((x: Int) => x * 2)

// more type inferenceList(1, 2, 3).map(x => x * 2)

// or even shorterList(1, 2, 3).map(_ * 2)

Functions with sugarmake code sweeter

Page 44: Scala presentation by Aleksandar Prokopec

var step = 1val inc = x => x + step

inc(5) 6step = 2inc(5) 7

Closuresfunctions that “capture” their environment

Page 45: Scala presentation by Aleksandar Prokopec

// Javabutton.addMouseListener(new MouseAdapter() { public void mouseEntered(MouseEvent e) { System.out.println(e); }}

// ScalalistenTo(button)reactions += { case e => println(e) }

First class functionsbecause you write them in Java all the time

Brijest
// a demoimport swing._object Converter extends SimpleSwingApplication { val button = new Button { text = "Click me" } def top = new MainFrame { title = "Example" contents = button listenTo(button) reactions += { case e => println(e) } }}
Page 46: Scala presentation by Aleksandar Prokopec

Pattern matching

Page 47: Scala presentation by Aleksandar Prokopec

Pattern matching…is concise

// Scalareactions += { case m: MouseEntered => println(“I see it!”) case m: MouseExited => println(“Lost it.”) case m: MouseClicked => println(“Poked!”)}

// Javabutton.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseEntered(MouseEvent e) { System.out.println(“I see it!”); } public void mouseExited(MouseEvent e) { System.out.println(“Lost it.”); } public void mouseClicked(MouseEvent e) { System.out.println(“Poked!”); }}

// ...alternative - isinstanceof

Page 48: Scala presentation by Aleksandar Prokopec

trait Treecase class Node(l: Tree, r: Tree) extends Treecase object Leaf extends Tree

Pattern matching…is precise

Page 49: Scala presentation by Aleksandar Prokopec

def b(t: Tree): Int = t match { case Node(Leaf, Node(_, _)) | Node(Node(_, _), Leaf) => -1 case Node(l, r) => val (ld, rd) = (b(l), b(r)) if (ld == rd) ld + 1 else -1 case Leaf => 0 case _ => error(“Unknown tree!”)}

Pattern matching…is precise

Page 50: Scala presentation by Aleksandar Prokopec

sealed trait Tree...def b(t: Tree): Int = t match { case Node(Leaf, Node(_, _)) | Node(Node(_, _), Leaf) => -1 case Node(l, r) => val (ld, rd) = (b(l), b(r)) if (ld == rd) ld + 1 else -1 case Leaf => 0}

Pattern matching…is exhaustive

Page 51: Scala presentation by Aleksandar Prokopec

def matchingMeSoftly(a: Any): Any = a match { case 11 => “eleven” case s: String => “’%s’”.format(s) case <tag>{t}</tag> => t case Array(1, 2, 3) => “1, 2, 3” case head :: tail => tail case _ => null }

Pattern matching…is extensible

Page 52: Scala presentation by Aleksandar Prokopec

Lazyness

Page 53: Scala presentation by Aleksandar Prokopec

lazy valuesdon’t compute if there’s no demand

class User(id: Int) { lazy val followernum = from(followers)(f => where(id === f.fid) compute(countDistinct(f.fid)) )}

Page 54: Scala presentation by Aleksandar Prokopec

Call by nameevaluate only when you have to

def withErrorOut(body: =>Unit) = { val old = Console.out Console.setOut(Console.err) try body finally Console.setOut(old)}...withErrorOut { if (n < 0) println(“n too small”)}

Page 55: Scala presentation by Aleksandar Prokopec

Streamslazy lists

e = ∑ 1/n!

= 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + …

Page 56: Scala presentation by Aleksandar Prokopec

Streamslazy lists

e = ∑ 1/n!

= 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + …

0! ?

Page 57: Scala presentation by Aleksandar Prokopec

Streamslazy lists

e = ∑ 1/n!

= 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + …

0! 1! 2! 3! ?

0! ?

Page 58: Scala presentation by Aleksandar Prokopec

Streamslazy lists

e = ∑ 1/n!

= 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + …

0! 1! 2! 3! ?

0! ?

0! 1/1! 1/2! 1/3! ?

Page 59: Scala presentation by Aleksandar Prokopec

Streamslazy lists

def fact(n: Int, p: Int): Stream[Int] = p #:: fact(n + 1, p * (n + 1))

val factorials = fact(0, 1)

val e = factorials.map(1./_).take(10).sum

Page 60: Scala presentation by Aleksandar Prokopec

Scala is expressive.

Page 61: Scala presentation by Aleksandar Prokopec

for comprehensionstraverse anything

for (x <- List(1, 2, 3)) println(x)List(1, 2, 3).foreach(x => println(x))

for (x <- 0 until 10) println(x)(0 until 10).foreach(x => println(x))Range(0, 10, 1).foreach(x => println(x))

Page 62: Scala presentation by Aleksandar Prokopec

for comprehensionsmap anything

for (x <- List(1, 2, 3)) yield x * 2List(1, 2, 3).map(x => x * 2)

for (x <- List(1, 2); y <- List(1, 2)) yield x * yList(1, 2).flatMap(x => List(1, 2).map(y => x * y)) List(1, 2, 2, 4)

Page 63: Scala presentation by Aleksandar Prokopec

for comprehensionslike SQL queries

for { p <- people if p.age > 25 s <- schools if p.degree == s.degree} yield (p, s)

// pairs of people older than 25 and// schools they possibly attended

Page 64: Scala presentation by Aleksandar Prokopec

Collectionseasy to create

val phonebook = Map( “Jean” -> “123456”, “Damien” -> “666666”)

val meetings = ArrayBuffer( “Dante”, “Damien”, “Sophie”)

println(phonebook(meetings(1)))

Page 65: Scala presentation by Aleksandar Prokopec

Collectionshigh-level combinators

// Javaboolean isOk = truefor (int i = 0; i < name.length(); i++) { if (isLetterOrDigit(name.charAt(i)) { isOk = false; break; }}

Page 66: Scala presentation by Aleksandar Prokopec

Collectionshigh-level combinators

// Scalaname.forall(_.isLetterOrDigit)

Page 67: Scala presentation by Aleksandar Prokopec

Collectionshigh-level combinators

// count the total number of different// surnames shared by at least 2 adultspeople

Page 68: Scala presentation by Aleksandar Prokopec

Collectionshigh-level combinators

// count the total number of different// surnames shared by at least 2 adultspeople.filter(_.age >= 18)

Page 69: Scala presentation by Aleksandar Prokopec

Collectionshigh-level combinators

// count the total number of different// surnames shared by at least 2 adultspeople.filter(_.age >= 18) .groupBy(_.surname): Map[String, List[Person]]

Page 70: Scala presentation by Aleksandar Prokopec

Collectionshigh-level combinators

// count the total number of different// surnames shared by at least 2 adultspeople.filter(_.age >= 18) .groupBy(_.surname): Map[String, List[Person]] .count { case (s, l) => l.size >= 2 }

Page 71: Scala presentation by Aleksandar Prokopec

Listsan immutable sequence

val countdown = List(3, 2, 1)

3 2 1

countdown

Page 72: Scala presentation by Aleksandar Prokopec

Listsan immutable sequence

val countdown = List(3, 2, 1)val longer = 4 :: countdown

3 2 14

countdown

longer

Page 73: Scala presentation by Aleksandar Prokopec

Listsan immutable sequence

val countdown = List(3, 2, 1)val longer = 4 :: countdownval fast = 10 :: countdown

3 2 14

10

countdown

longer

fast

Page 74: Scala presentation by Aleksandar Prokopec

Listsan immutable sequence

val countdown = List(3, 2, 1)val longer = 4 :: countdownval fast = 10 :: countdownval withzero = countdown ::: List(0)

3 2 14

10

3 2 1 0

countdown

longer

fast

withzero

Page 75: Scala presentation by Aleksandar Prokopec

Buffersmutable sequences

val b = ArrayBuffer(1, 2, 3)b += 4b += 5b += 6 ArrayBuffer(1, 2, 3, 4, 5, 6)

Page 76: Scala presentation by Aleksandar Prokopec

Mapsmutable or immutable, sorted or unsorted

import collection._

val m = mutable.Map(“Heidfeld” -> 1, “Schumacher” -> 2)m += “Hakkinen” -> 3

val im = immutable.Map(“Schumacher” -> 1)

Page 77: Scala presentation by Aleksandar Prokopec

Hash triespersistence through efficient structural sharing

val im0: Map[Int, Int] = ...

im0

Page 78: Scala presentation by Aleksandar Prokopec

Hash triespersistence through efficient structural sharing

val im0: Map[Int, Int] = ...val im1 = im0 + (1 -> 1)

im0 im1

Page 79: Scala presentation by Aleksandar Prokopec

Hash triespersistence through efficient structural sharing

val im0: Map[Int, Int] = ...val im1 = im0 + (1 -> 1)val im2 = im1 + (2 -> 2)

im0 im1 im2

Page 80: Scala presentation by Aleksandar Prokopec

Hash triespersistence through efficient structural sharing

val im0: Map[Int, Int] = ...val im1 = im0 + (1 -> 1)val im2 = im1 + (2 -> 2)val im3 = im2 + (3 -> 6)

im0 im1 im2 im3

Page 81: Scala presentation by Aleksandar Prokopec

Hash triespersistence through efficient structural sharing

im0 im1 im2 im3

2x-3x slower lookup2x faster iteration

Page 82: Scala presentation by Aleksandar Prokopec

Parallel collectionsparallelize bulk operations on collections

def cntEqlen(m: Map[String, String]) = { m.par.count { case (n, s) => n.length == s.length }}

// be careful with side-effects

Page 83: Scala presentation by Aleksandar Prokopec

Scala is extensible.

Page 84: Scala presentation by Aleksandar Prokopec

One ring to rule them all.

Page 85: Scala presentation by Aleksandar Prokopec

actorsroad to safer concurrency

val a = actor { react { case i: Int => println(i) }}...a ! 5

Page 86: Scala presentation by Aleksandar Prokopec

Custom control flowit’s all about control

def myWhile(c: =>Boolean)(b: =>Unit) { if (c) { b myWhile(c)(b) }}

Page 87: Scala presentation by Aleksandar Prokopec

Custom control flowit’s all about control

@tailrecdef myWhile(c: =>Boolean)(b: =>Unit) { if (c) { b myWhile(c)(b) }}

Page 88: Scala presentation by Aleksandar Prokopec

Custom control flowit’s all about control

@tailrecdef myWhile(c: =>Boolean)(b: =>Unit) { if (c) { b myWhile(c)(b) }}var i = 0myWhile (i < 5) { i += 1}

Page 89: Scala presentation by Aleksandar Prokopec

ARMautomatic resource management

withFile (“~/.bashrc”) { f => for (l <- f.lines) { if (“#”.r.findFirstIn(l) != None) println(l) }}

Page 90: Scala presentation by Aleksandar Prokopec

ScalaTestbehavioral testing framework

“A list” should { “be a double reverse of itself” in { val ls = List(1, 2, 3, 4, 5, 6) ls.reverse.reverse should equal (ls) } }

Page 91: Scala presentation by Aleksandar Prokopec

BaySickBasic DSL in Scala

10 PRINT “Baysick Lunar Lander v0.9”20 LET ('dist := 100)30 LET ('v := 1)40 LET ('fuel := 1000)50 LET ('mass := 1000)...

Page 92: Scala presentation by Aleksandar Prokopec

implicit conversionsaugmenting types with new operations

‘a’.toUpperCase

Page 93: Scala presentation by Aleksandar Prokopec

implicit conversionsaugmenting types with new operations

implicit def charOps(c: Char) = new { def toUpperCase = if (c >= ‘a’ && c <= ‘z’)

(c – 32).toChar else c}...‘a’.toUpperCase

Page 94: Scala presentation by Aleksandar Prokopec

Pimp my library

Page 95: Scala presentation by Aleksandar Prokopec

implicit conversionspimping your libraries since 2006

import scalaj.collection._

val list = new java.util.ArrayList[Int]list.add(1)list.add(2)list.add(3)...for (x <- list) yield x * 2

Page 96: Scala presentation by Aleksandar Prokopec

implicit conversionspimping your libraries since 2006

import scalaj.collection._

val list = new java.util.ArrayList[Int]list.add(1)list.add(2)list.add(3)...for (x <- list) yield x * 2// list.map(x => x * 2)

Page 97: Scala presentation by Aleksandar Prokopec

implicit conversionspimping your libraries since 2006

import scalaj.collection._

val list = new java.util.ArrayList[Int]list.add(1)list.add(2)list.add(3)...for (x <- list) yield x * 2// jlist2slist(list).map(x => x * 2)

Page 98: Scala presentation by Aleksandar Prokopec

implicit argumentsrestricting operations on types

val is = SortedSet(1, 2, 3)

case class Man(id: Int)...implicit object MenOrd extends Ordering[Man] { def compare(x: Man, y: Man) = x.id – y.id}

val ms = SortedSet(Person(1), Person(2))

Page 99: Scala presentation by Aleksandar Prokopec

STMsoftware transactional memory

val account1 = cell[Int]val account2 = cell[Int]

atomic { implicit txn => if (account2() >= 50) { account1 += 50 account2 -= 50 }}

Page 100: Scala presentation by Aleksandar Prokopec

Scala has support.

Page 101: Scala presentation by Aleksandar Prokopec

BuildingAntSBTMaven

Page 102: Scala presentation by Aleksandar Prokopec

SBTsimple build tool

> compile...> ~compile...> test...> package

Page 103: Scala presentation by Aleksandar Prokopec

SBTproject definition written in Scala

val scalatest = “org.scala-tools.testing” % “scalatest” % “0.9.5”

...

> reload[INFO] Building project ...[INFO] using sbt.Default ...> update

Page 104: Scala presentation by Aleksandar Prokopec

Tools: IDEsEclipseNetbeansIntelliJ IDEAEmacs ENSIMEJEdit

Page 105: Scala presentation by Aleksandar Prokopec

Web frameworks

Page 106: Scala presentation by Aleksandar Prokopec

Used by...

Page 107: Scala presentation by Aleksandar Prokopec

Thank you!