208
The Seductions of Scala 1 Dean Wampler [email protected] @deanwampler polyglotprogramming.com/talks April 3, 2011

Seductions of Scala

Embed Size (px)

DESCRIPTION

A 90-minute introduction to the Scala programming language and why it's a seductive choice for modern software development.

Citation preview

Page 2: Seductions of Scala

Co-author,Programming

Scala

programmingscala.com

2

<shameless-plug/>

Page 3: Seductions of Scala

Why do we need a new language?

3

Page 4: Seductions of Scala

#1We needFunctional

Programming…

4

Page 5: Seductions of Scala

… for concurrency.… for concise code.… for correctness.

5

Page 6: Seductions of Scala

#2We need a better

Object Model…

6

Page 7: Seductions of Scala

… for composability.… for scalable designs.

7

Page 8: Seductions of Scala

Scala’s Thesis: Functional Prog.

Complements Object-Oriented

Prog.

8

Page 9: Seductions of Scala

Scala’s Thesis: Functional Prog.

Complements Object-Oriented

Prog.Despite surface contradictions...

8

Page 10: Seductions of Scala

But we want tokeep our investment

in Java/C#.

9

Page 11: Seductions of Scala

Scala is...

• A JVM and .NET language.

• Functional and object oriented.

• Statically typed.

• An improved Java/C#.

10

Page 12: Seductions of Scala

Martin Odersky

• Helped design java generics.

• Co-wrote GJ that became javac (v1.3+).

• Understands Computer Science and Industry.

11

Page 13: Seductions of Scala

Everything can be a Function

12

Page 14: Seductions of Scala

Objects as

Functions13

Page 15: Seductions of Scala

14

class Logger(val level:Level) {

def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) }}

Page 16: Seductions of Scala

class Logger(val level:Level) {

def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) }}

15

Page 17: Seductions of Scala

class Logger(val level:Level) {

def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) }}

15

class body is the “primary” constructor

Page 18: Seductions of Scala

class Logger(val level:Level) {

def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) }}

15

makes “level” a field

class body is the “primary” constructor

Page 19: Seductions of Scala

class Logger(val level:Level) {

def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) }}

15

makes “level” a field

class body is the “primary” constructor

method

Page 20: Seductions of Scala

16

class Logger(val level:Level) {

def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) }}

Page 21: Seductions of Scala

val error = new Logger(ERROR)

16

class Logger(val level:Level) {

def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) }}

Page 22: Seductions of Scala

val error = new Logger(ERROR)

16

class Logger(val level:Level) {

def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) }}

…error("Network error.")

Page 23: Seductions of Scala

17

class Logger(val level:Level) {

def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) }}

…error("Network error.")

Page 24: Seductions of Scala

17

class Logger(val level:Level) {

def apply(message: String) = { // pass to Log4J... Log4J.log(level, message) }}

…error("Network error.")

“function object”apply is called

Page 25: Seductions of Scala

When you put an arg list

after any object,apply is called.

18

Page 26: Seductions of Scala

Everything is an Object

19

Page 27: Seductions of Scala

Int, Double, etc. are true objects.

20

Page 28: Seductions of Scala

Int, Double, etc. are true objects.

20

But they are compiled to primitives.

Page 29: Seductions of Scala

Functions as

Objects21

Page 30: Seductions of Scala

First, About Lists

22

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

Page 31: Seductions of Scala

First, About Lists

The same as this “list literal” syntax:

22

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

val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil

Page 32: Seductions of Scala

val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil

23

Page 33: Seductions of Scala

val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil

23

“cons”

Page 34: Seductions of Scala

val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil

empty list

23

“cons”

Page 35: Seductions of Scala

val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil

empty list

23

“cons”

head

Page 36: Seductions of Scala

val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil

empty list

23

“cons”

tailhead

Page 37: Seductions of Scala

val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil

24

Baked into the Grammar?

Page 38: Seductions of Scala

val list = Nil.::(5).::(4).::( 3).::(2).::(1)

val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil

No, just method calls!

24

Baked into the Grammar?

Page 39: Seductions of Scala

val list = Nil.::(5).::(4).::( 3).::(2).::(1)

val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil

25

Page 40: Seductions of Scala

val list = Nil.::(5).::(4).::( 3).::(2).::(1)

val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil

25

Method names can contain almost any character.

Page 41: Seductions of Scala

val list = Nil.::(5).::(4).::( 3).::(2).::(1)

val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil

26

Any method ending in “:” binds to the right!

Page 42: Seductions of Scala

val list = Nil.::(5).::(4).::( 3).::(2).::(1)

val list = 1 :: 2 :: 3 :: 4 :: 5 :: Nil

27

If a method takes one argument, you can drop the “.” and the parentheses, “(“ and “)”.

Page 43: Seductions of Scala

"hello" + "world"

28

Infix Operator Notation

Page 44: Seductions of Scala

"hello" + "world"

is actually just

28

Infix Operator Notation

"hello".+("world")

Page 45: Seductions of Scala

Similar mini-DSLs have been defined for other types.

29

Page 46: Seductions of Scala

Similar mini-DSLs have been defined for other types.

29

Also in many third-party libraries.

Page 47: Seductions of Scala

Back tofunctions as objects...

30

Page 48: Seductions of Scala

Classic Operations on “Container” Types

31

List, Map, ... map

fold/reduce

filter

Page 49: Seductions of Scala

32

val list = "a" :: "b" :: Nil

Page 50: Seductions of Scala

32

list map { s => s.toUpperCase }

// => "A" :: "B" :: Nil

val list = "a" :: "b" :: Nil

Page 51: Seductions of Scala

33

list map { s => s.toUpperCase }

Page 52: Seductions of Scala

33

list map { s => s.toUpperCase }

map called on list (dropping the “.”)

Page 53: Seductions of Scala

33

list map { s => s.toUpperCase }

map called on list (dropping the “.”) argument to map

(using “{“ vs. “(“)

Page 54: Seductions of Scala

33

list map { s => s.toUpperCase }

map called on list (dropping the “.”) argument to map

(using “{“ vs. “(“)

“function literal”

Page 55: Seductions of Scala

33

list map { s => s.toUpperCase }

map called on list (dropping the “.”)

functionargument list

argument to map (using “{“ vs. “(“)

“function literal”

Page 56: Seductions of Scala

33

list map { s => s.toUpperCase }

map called on list (dropping the “.”)

functionargument list

function body

argument to map (using “{“ vs. “(“)

“function literal”

Page 57: Seductions of Scala

34

list map { s => s.toUpperCase }

Page 58: Seductions of Scala

34

list map { s => s.toUpperCase }

inferred type

Page 59: Seductions of Scala

34

list map { s => s.toUpperCase }

list map { (s:String) => s.toUpperCase }

Explicit type

inferred type

Page 60: Seductions of Scala

So far, we have usedtype inference

a lot...

35

Page 61: Seductions of Scala

How the Sausage Is Made

class List[A] { … def map[B](f: A => B): List[B] …}

36

Page 62: Seductions of Scala

How the Sausage Is Made

class List[A] { … def map[B](f: A => B): List[B] …}

36

Parameterized type

Page 63: Seductions of Scala

How the Sausage Is Made

class List[A] { … def map[B](f: A => B): List[B] …}

36

Declaration of map

The function argument

Parameterized type

map’s return type

Page 64: Seductions of Scala

How the Sausage Is Made

trait Function1[-A,+R] {

 def apply(a:A): R …}

37

Page 65: Seductions of Scala

How the Sausage Is Made

trait Function1[-A,+R] {

 def apply(a:A): R …}

37

like an “abstract” class

Page 66: Seductions of Scala

How the Sausage Is Made

trait Function1[-A,+R] {

 def apply(a:A): R …}

37

No method body:=> abstract

like an “abstract” class

Page 67: Seductions of Scala

How the Sausage Is Made

trait Function1[-A,+R] {

 def apply(a:A): R …}

37

No method body:=> abstract

like an “abstract” class“contravariant”,

“covariant” typing

Page 68: Seductions of Scala

(s:String) => s.toUpperCase

38

new Function1[String,String] { def apply(s:String) = { s.toUpperCase }}

What the Compiler Does

Page 69: Seductions of Scala

(s:String) => s.toUpperCase

38

What you write.

new Function1[String,String] { def apply(s:String) = { s.toUpperCase }}

What the compiler generates

An anonymous class

What the Compiler Does

Page 70: Seductions of Scala

(s:String) => s.toUpperCase

38

What you write.

new Function1[String,String] { def apply(s:String) = { s.toUpperCase }}

What the compiler generates

An anonymous class

What the Compiler Does

No “return” needed

Page 71: Seductions of Scala

Recap

39

list map { s => s.toUpperCase }

// => "A" :: "B" :: Nil

val list = "a" :: "b" :: Nil

Page 72: Seductions of Scala

Recap

39

list map { s => s.toUpperCase }

// => "A" :: "B" :: Nil

val list = "a" :: "b" :: Nil

Function “object”

Page 73: Seductions of Scala

Recap

39

list map { s => s.toUpperCase }

// => "A" :: "B" :: Nil

val list = "a" :: "b" :: Nil

Function “object”

{…} ok, instead of (…)

Page 74: Seductions of Scala

More Functional

Hotness40

Page 75: Seductions of Scala

sealed abstract class Option[+T] {…}

case class Some[+T](value: T) extends Option[T] {…}

case object None extends Option[Nothing] {…}

Avoiding Nulls

41

Page 76: Seductions of Scala

sealed abstract class Option[+T] {…}

case class Some[+T](value: T) extends Option[T] {…}

case object None extends Option[Nothing] {…}

Avoiding Nulls

41An Algebraic Data Type

Page 77: Seductions of Scala

// Java style (schematic) class Map[K, V] { def get(key: K): V = { return value || null; }}

42

Page 78: Seductions of Scala

// Java style (schematic) class Map[K, V] { def get(key: K): V = { return value || null; }}

42

Page 79: Seductions of Scala

// Java style (schematic) class Map[K, V] { def get(key: K): V = { return value || null; }}

42Which is the better API?

// Scala styleclass Map[K, V] { def get(key: K): Option[V] = { return Some(value) || None; }}

Page 80: Seductions of Scala

val m = Map("one" -> 1, "two" -> 2)…val n = m.get("four") match { case Some(i) => i case None => 0 // default}

43

In Use:

Page 81: Seductions of Scala

val m = Map("one" -> 1, "two" -> 2)…val n = m.get("four") match { case Some(i) => i case None => 0 // default}

43

Use pattern matching to extract the value (or not)

In Use:Literal syntax for map creation

Page 82: Seductions of Scala

sealed abstract class Option[+T] {…}

Option Details: sealed

44

Page 83: Seductions of Scala

sealed abstract class Option[+T] {…}

Option Details: sealed

44

All children must be defined in the same file

Page 84: Seductions of Scala

case class Some[+T](value: T)

Case Classes

45

Page 85: Seductions of Scala

case class Some[+T](value: T)

Case Classes

45

●Provides factory method, pattern matching, equals, toString, etc.●Makes “value” a field without val keyword.

Page 86: Seductions of Scala

Object

46

case object None extends Option[Nothing] {…}

Page 87: Seductions of Scala

Object

46

A “singleton”. Only one instance will exist.

case object None extends Option[Nothing] {…}

Page 88: Seductions of Scala

case object None extends Option[Nothing] {…}

Nothing

47

Page 89: Seductions of Scala

case object None extends Option[Nothing] {…}

Nothing

47

Special child type of all other types. Used for this special

case where no actual instances required.

Page 90: Seductions of Scala

Succinct Code 48

Page 91: Seductions of Scala

Succinct Code 48

A few things we’ve seen so far.

Page 92: Seductions of Scala

"hello" + "world"

Infix Operator Notation

49

Page 93: Seductions of Scala

same as

"hello" + "world"

"hello".+("world")

Infix Operator Notation

49

Page 94: Seductions of Scala

Type Inference

50

// JavaHashMap<String,Person> persons = new HashMap<String,Person>();

Page 95: Seductions of Scala

Type Inference

50

// JavaHashMap<String,Person> persons = new HashMap<String,Person>();

vs.

// Scalaval persons = new HashMap[String,Person]

Page 96: Seductions of Scala

Type Inference

51

// JavaHashMap<String,Person> persons = new HashMap<String,Person>();

vs.

// Scalaval persons = new HashMap[String,Person]

Page 97: Seductions of Scala

Type Inference

51

// JavaHashMap<String,Person> persons = new HashMap<String,Person>();

vs.

// Scalaval persons = new HashMap[String,Person]

Page 98: Seductions of Scala

52

// Scalaval persons = new HashMap[String,Person]

Page 99: Seductions of Scala

52

// Scalaval persons = new HashMap[String,Person]

no () needed.Semicolons inferred.

Page 100: Seductions of Scala

User-defined Factory Methods

53

val words = List("Scala", "is", "fun!")

Page 101: Seductions of Scala

User-defined Factory Methods

53

val words = List("Scala", "is", "fun!")

no new needed.Can return a subtype!

Page 102: Seductions of Scala

class Person { private String firstName; private String lastName; private int age;

public Person(String firstName, String lastName, int age){ this.firstName = firstName; this.lastName = lastName; this.age = age; } public void String getFirstName() {return this.firstName;} public void setFirstName(String firstName) { this.firstName = firstName; }

public void String getLastName() {return this.lastName;} public void setLastName(String lastName) { this.lastName = lastName; }

public void int getAge() {return this.age;} public void setAge(int age) { this.age = age; } } 54

Page 103: Seductions of Scala

class Person { private String firstName; private String lastName; private int age;

public Person(String firstName, String lastName, int age){ this.firstName = firstName; this.lastName = lastName; this.age = age; } public void String getFirstName() {return this.firstName;} public void setFirstName(String firstName) { this.firstName = firstName; }

public void String getLastName() {return this.lastName;} public void setLastName(String lastName) { this.lastName = lastName; }

public void int getAge() {return this.age;} public void setAge(int age) { this.age = age; } }

Typical Java54

Page 104: Seductions of Scala

class Person( var firstName: String, var lastName: String, var age: Int)

55

Page 105: Seductions of Scala

class Person( var firstName: String, var lastName: String, var age: Int)

55

Typical Scala!

Page 106: Seductions of Scala

class Person( var firstName: String, var lastName: String, var age: Int)

56

Page 107: Seductions of Scala

class Person( var firstName: String, var lastName: String, var age: Int)

Class body is the“primary” constructor

Parameter list for c’tor

Makes the arg a fieldwith accessors

No class body {…}. nothing else needed!

56

Page 108: Seductions of Scala

case class Person( firstName: String, lastName: String, age: Int)

57

Even Better...

Page 109: Seductions of Scala

case class Person( firstName: String, lastName: String, age: Int)

57

Constructor args are automatically vals, plus other goodies.

Even Better...

Page 110: Seductions of Scala

Scala’s Object Model: Traits

58

Page 111: Seductions of Scala

Scala’s Object Model: Traits

58

Composable Units of Behavior

Page 112: Seductions of Scala

We would like to compose objects

from mixins.

59

Page 113: Seductions of Scala

Java: What to Do?class Server extends Logger { … }

60

Page 114: Seductions of Scala

Java: What to Do?class Server extends Logger { … }

60

“Server is a Logger”?

Page 115: Seductions of Scala

Java: What to Do?class Server extends Logger { … }

60

class Server implements Logger { … }

“Server is a Logger”?

Logger isn’t an interface!

Page 116: Seductions of Scala

Java’s object model

61

Page 117: Seductions of Scala

Java’s object model

• Good

• Promotes abstractions.

• Bad

• No composition through reusable mixins.

61

Page 118: Seductions of Scala

Like interfaces with implementations,

62

Traits

Page 119: Seductions of Scala

… or like abstract classes +

multiple inheritance (if you prefer).

63

Traits

Page 120: Seductions of Scala

64

trait Logger { val level: Level // abstract

def log(message: String) = { Log4J.log(level, message) }}

Logger as a Mixin:

Page 121: Seductions of Scala

64

trait Logger { val level: Level // abstract

def log(message: String) = { Log4J.log(level, message) }}

Logger as a Mixin:

Traits don’t have constructors, but

you can still define fields.

Page 122: Seductions of Scala

65

trait Logger { val level: Level // abstract …}

Logger as a Mixin:

Page 123: Seductions of Scala

val server = new Server(…) with Logger { val level = ERROR }server.log("Internet down!!")

65

trait Logger { val level: Level // abstract …}

Logger as a Mixin:

Page 124: Seductions of Scala

val server = new Server(…) with Logger { val level = ERROR }server.log("Internet down!!")

65

trait Logger { val level: Level // abstract …}

Logger as a Mixin:

mixed in Logging

Page 125: Seductions of Scala

val server = new Server(…) with Logger { val level = ERROR }server.log("Internet down!!")

65

trait Logger { val level: Level // abstract …}

Logger as a Mixin:

mixed in Logging

abstract member defined

Page 126: Seductions of Scala

Actor Concurrency

66

Page 127: Seductions of Scala

When you share mutable

state...

67

Page 128: Seductions of Scala

When you share mutable

state...

Hic sunt dracones(Here be dragons)

67

Page 129: Seductions of Scala

Actor Model

• Message passing between autonomous actors.

• No shared (mutable) state.

68

Page 130: Seductions of Scala

Actor Model

• First developed in the 70’s by Hewitt, Agha, Hoare, etc.

• Made “famous” by Erlang.

• Scala’s Actors patterned after Erlang’s.

69

Page 131: Seductions of Scala

“self” Display

draw

draw

??? error!

exit“exit”

2 Actors:

70

Page 132: Seductions of Scala

package shapes

case class Point( x: Double, y: Double) abstract class Shape { def draw() }

Hierarchy of geometric shapes71

Page 133: Seductions of Scala

package shapes

case class Point( x: Double, y: Double) abstract class Shape { def draw() }

abstract “draw” method

Hierarchy of geometric shapes71

Page 134: Seductions of Scala

case class Circle( center:Point, radius:Double) extends Shape { def draw() = …}

case class Rectangle( ll:Point, h:Double, w:Double) extends Shape { def draw() = …}

72

Page 135: Seductions of Scala

case class Circle( center:Point, radius:Double) extends Shape { def draw() = …}

case class Rectangle( ll:Point, h:Double, w:Double) extends Shape { def draw() = …}

concrete “draw” methods

72

Page 136: Seductions of Scala

package shapes import akka.actor._ class ShapeDrawingActor extends Actor { def receive = { … }}

73

Actor for drawing shapes

Page 137: Seductions of Scala

package shapes import akka.actor._ class ShapeDrawingActor extends Actor { def receive = { … }}

73

Use the “Akka” Actor library

Actor for drawing shapes

Page 138: Seductions of Scala

package shapes import akka.actor._ class ShapeDrawingActor extends Actor { def receive = { … }}

73

Use the “Akka” Actor library

Actor

receive and handle each message

Actor for drawing shapes

Page 139: Seductions of Scala

receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x)}

74

Receive method

Actor for drawing shapes

Page 140: Seductions of Scala

receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x)}

75

Actor for drawing shapes

Page 141: Seductions of Scala

receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x)}

75

pattern matching

Actor for drawing shapes

Page 142: Seductions of Scala

receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x)}

75

pattern matching

Actor for drawing shapes

Page 143: Seductions of Scala

receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x)}

75

pattern matching

Actor for drawing shapes

Page 144: Seductions of Scala

receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x)}

76

Page 145: Seductions of Scala

receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x)}

draw shape & send reply

76

Page 146: Seductions of Scala

receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x)}

done

76

Page 147: Seductions of Scala

receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x)}

unrecognized message76

Page 148: Seductions of Scala

receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x)}

76

Page 149: Seductions of Scala

77

package shapes import akka.actor._class ShapeDrawingActor extends Actor { receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) }}

Page 150: Seductions of Scala

Altogether77

package shapes import akka.actor._class ShapeDrawingActor extends Actor { receive = { case s:Shape => print("-> "); s.draw() self.reply("Shape drawn.") case "exit" => println("-> exiting...") self.reply("good bye!") case x => // default println("-> Error: " + x) self.reply("Unknown: " + x) }}

Page 151: Seductions of Scala

import shapes._import akka.actor._import akka.actor.Actor

object Driver { def main(args:Array[String])={ val driver = actorOf[Driver] driver.start driver ! "go!" }}class Driver …

78

Page 152: Seductions of Scala

import shapes._import akka.actor._import akka.actor.Actor

object Driver { def main(args:Array[String])={ val driver = actorOf[Driver] driver.start driver ! "go!" }}class Driver … driver to try it out

78

a “singleton” type to hold main

Page 153: Seductions of Scala

import shapes._import akka.actor._import akka.actor.Actor

object Driver { def main(args:Array[String])={ val driver = actorOf[Driver] driver.start driver ! "go!" }}class Driver … driver to try it out

78

a “singleton” type to hold main

Page 154: Seductions of Scala

import shapes._import akka.actor._import akka.actor.Actor

object Driver { def main(args:Array[String])={ val driver = actorOf[Driver] driver.start driver ! "go!" }}class Driver … driver to try it out

78

a “singleton” type to hold main

! is the message send “operator”

Page 155: Seductions of Scala

…class Driver extends Actor { val drawer = actorOf[ShapeDrawingActor] drawer.start def receive = { … }}

driver to try it out79

Page 156: Seductions of Scala

…class Driver extends Actor { val drawer = actorOf[ShapeDrawingActor] drawer.start def receive = { … }}

driver to try it out79

Its “companion” object Driver was on the previous slide.

Page 157: Seductions of Scala

def receive = { case "go!" => drawer ! Circle(Point(…),…) drawer ! Rectangle(…) drawer ! 3.14159 drawer ! "exit" case "good bye!" => println("<- cleaning up…") drawer.stop; self.stop case other => println("<- " + other)}

80

driver to try it out

Page 158: Seductions of Scala

def receive = { case "go!" => drawer ! Circle(Point(…),…) drawer ! Rectangle(…) drawer ! 3.14159 drawer ! "exit" case "good bye!" => println("<- cleaning up…") drawer.stop; self.stop case other => println("<- " + other)}

80

driver to try it out

sent by main

Page 159: Seductions of Scala

def receive = { case "go!" => drawer ! Circle(Point(…),…) drawer ! Rectangle(…) drawer ! 3.14159 drawer ! "exit" case "good bye!" => println("<- cleaning up…") drawer.stop; self.stop case other => println("<- " + other)}

80

driver to try it out

sent by main

sent bydrawer

Page 160: Seductions of Scala

// run Driver.main (see github README.md)-> drawing: Circle(Point(0.0,0.0),1.0)-> drawing: Rectangle(Point(0.0,0.0),2.0,5.0)-> Error: 3.14159-> exiting...<- Shape drawn.<- Shape drawn.<- Unknown: 3.14159<- cleaning up...

81

“<-” and “->” messages may be interleaved!!

case "go!" => drawer ! Circle(Point(…),…) drawer ! Rectangle(…) drawer ! 3.14159 drawer ! "exit"

Page 161: Seductions of Scala

… // ShapeDrawingActorreceive = { case s:Shape => s.draw() self.reply("…")

case … case … }

82

Page 162: Seductions of Scala

… // ShapeDrawingActorreceive = { case s:Shape => s.draw() self.reply("…")

case … case … }

Functional-style pattern matching

82

Page 163: Seductions of Scala

… // ShapeDrawingActorreceive = { case s:Shape => s.draw() self.reply("…")

case … case … }

Functional-style pattern matching

“Switch” statements are not evil!

Object-oriented-style polymorphism

82

Page 164: Seductions of Scala

Recap

83

Page 165: Seductions of Scala

Scala is...

84

Page 166: Seductions of Scala

85

Page 167: Seductions of Scala

a better Java and C#,

85

Page 168: Seductions of Scala

86

Page 169: Seductions of Scala

object-orientedand

functional,86

Page 170: Seductions of Scala

87

Page 171: Seductions of Scala

succinct, elegant,

andpowerful.

87

Page 173: Seductions of Scala

Extra Slides 89

Page 174: Seductions of Scala

Modifying Existing Behaviorwith Traits

90

Page 175: Seductions of Scala

Example

trait Queue[T] { def get(): T def put(t: T) }

91

Page 176: Seductions of Scala

Example

trait Queue[T] { def get(): T def put(t: T) }

A pure abstraction (in this case...)91

Page 177: Seductions of Scala

Log put trait QueueLogging[T] extends Queue[T] { abstract override def put( t: T) = { println("put("+t+")") super.put(t) }}

92

Page 178: Seductions of Scala

Log put trait QueueLogging[T] extends Queue[T] { abstract override def put( t: T) = { println("put("+t+")") super.put(t) }}

93

Page 179: Seductions of Scala

Log put trait QueueLogging[T] extends Queue[T] { abstract override def put( t: T) = { println("put("+t+")") super.put(t) }}

What is “super” bound to??

93

Page 180: Seductions of Scala

class StandardQueue[T] extends Queue[T] { import ...ArrayBuffer private val ab = new ArrayBuffer[T] def put(t: T) = ab += t def get() = ab.remove(0) … }

94

Page 181: Seductions of Scala

class StandardQueue[T] extends Queue[T] { import ...ArrayBuffer private val ab = new ArrayBuffer[T] def put(t: T) = ab += t def get() = ab.remove(0) … }

Concrete (boring) implementation94

Page 182: Seductions of Scala

val sq = new StandardQueue[Int] with QueueLogging[Int] sq.put(10) // #1 println(sq.get()) // #2 // => put(10) (on #1) // => 10 (on #2)

95

Page 183: Seductions of Scala

val sq = new StandardQueue[Int] with QueueLogging[Int] sq.put(10) // #1 println(sq.get()) // #2 // => put(10) (on #1) // => 10 (on #2)

Example use95

Page 184: Seductions of Scala

val sq = new StandardQueue[Int] with QueueLogging[Int] sq.put(10) // #1 println(sq.get()) // #2 // => put(10) (on #1) // => 10 (on #2)

96

Page 185: Seductions of Scala

val sq = new StandardQueue[Int] with QueueLogging[Int] sq.put(10) // #1 println(sq.get()) // #2 // => put(10) (on #1) // => 10 (on #2)

Mixin composition; no class required

96

Example use

Page 186: Seductions of Scala

Traits give us advice, but not a join point “query” language.

97

Like Aspect-Oriented Programming?

Page 187: Seductions of Scala

Traits are a powerful composition mechanism!

98

Page 188: Seductions of Scala

Functional Programming

99

Page 189: Seductions of Scala

What is Functional

Programming?

100

Page 190: Seductions of Scala

What is Functional

Programming?Don’t we already write “functions”?

100

Page 191: Seductions of Scala

y = sin(x)

101

Page 192: Seductions of Scala

y = sin(x)

101

Based on Mathematics

Page 193: Seductions of Scala

y = sin(x)

102

Page 194: Seductions of Scala

y = sin(x)

Setting x fixes y

∴ variables are immutable102

Page 195: Seductions of Scala

20 += 1 ??

103

Page 196: Seductions of Scala

20 += 1 ??We never modify the 20 “object”

103

Page 197: Seductions of Scala

Concurrency

104

Page 198: Seductions of Scala

No mutable state

∴ nothing to synchronize

Concurrency

104

Page 199: Seductions of Scala

When you share mutable

state...

105

Page 200: Seductions of Scala

When you share mutable

state...

Hic sunt dracones(Here be dragons)

105

Page 201: Seductions of Scala

y = sin(x)

106

Page 202: Seductions of Scala

y = sin(x)Functions don’t

change state∴ side-effect free

106

Page 203: Seductions of Scala

Side-effect free functions

• Easy to reason about behavior.

• Easy to invoke concurrently.

• Easy to invoke anywhere.

• Encourage immutable objects.

107

Page 204: Seductions of Scala

tan(Θ) = sin(Θ)/cos(Θ)

108

Page 205: Seductions of Scala

tan(Θ) = sin(Θ)/cos(Θ)

Compose functions of other functions

∴ first-class citizens108

Page 206: Seductions of Scala

Even More Functional

Hotness109

Page 207: Seductions of Scala

val l = List( Some("a"), None, Some("b"), None, Some("c"))

for (Some(s) <- l) yield s// List(a, b, c)

110

For “Comprehensions”

Page 208: Seductions of Scala

val l = List( Some("a"), None, Some("b"), None, Some("c"))

for (Some(s) <- l) yield s// List(a, b, c)

110

No “if ” statement

Pattern match; only take elements of “l”

that are Somes.

For “Comprehensions”