Slide 1

Slide 1 text

pICKLES &sPORES HEATHER MILLER On IMPROVING SCALA’S SUPPORT FOR DISTRIBUTED PROGRAMMING

Slide 2

Slide 2 text

plug: http://lampwww.epfl.ch/~hmiller/scala2013/

Slide 3

Slide 3 text

pICKLES &sPORES HEATHER MILLER On IMPROVING SCALA’S SUPPORT FOR DISTRIBUTED PROGRAMMING

Slide 4

Slide 4 text

with: PHILIPP HALLER EUGENE BURMAKO MARTIN ODERSKY TYPESAFE EPFL EPFL/TYPESAFE

Slide 5

Slide 5 text

wHAT IS THIS TALK ABOUT?

Slide 6

Slide 6 text

wHAT IS THIS TALK ABOUT? Making distributed programming easier in scala

Slide 7

Slide 7 text

This kind of distributed system

Slide 8

Slide 8 text

This kind of distributed system insert social network of your choice here ALso!

Slide 9

Slide 9 text

Bottomline: Machines Communicating

Slide 10

Slide 10 text

Bottomline: Machines Communicating How can we simplify distribution at the language-level?

Slide 11

Slide 11 text

sCALA pICKLING Agenda macros & typeclasses Spores

Slide 12

Slide 12 text

sCALA pICKLING Agenda Spores

Slide 13

Slide 13 text

Pickles! scala.pickling https://github.com/scala/pickling

Slide 14

Slide 14 text

What is it? https://github.com/scala/pickling

Slide 15

Slide 15 text

What is it? PICKLING == SERIALIZATION == MARSHALLING https://github.com/scala/pickling

Slide 16

Slide 16 text

What is it? PICKLING == SERIALIZATION == MARSHALLING very different from java serialization https://github.com/scala/pickling

Slide 17

Slide 17 text

wait, why do we care? https://github.com/scala/pickling

Slide 18

Slide 18 text

Slow! wait, why do we care? https://github.com/scala/pickling

Slide 19

Slide 19 text

Closed! Slow! wait, why do we care? https://github.com/scala/pickling

Slide 20

Slide 20 text

Closed! Slow! wait, why do we care? not serializable exceptions at runtime https://github.com/scala/pickling

Slide 21

Slide 21 text

Closed! Slow! wait, why do we care? not serializable exceptions at runtime can’t retroactively make classes serializable https://github.com/scala/pickling

Slide 22

Slide 22 text

Enter: Scala Pickling https://github.com/scala/pickling

Slide 23

Slide 23 text

Enter: Scala Pickling fast: Serialization code generated at compile- time and inlined at the use-site. https://github.com/scala/pickling

Slide 24

Slide 24 text

Enter: Scala Pickling fast: Serialization code generated at compile- time and inlined at the use-site. Flexible: Using typeclass pattern, retroactively make types serializable https://github.com/scala/pickling

Slide 25

Slide 25 text

Enter: Scala Pickling fast: Serialization code generated at compile- time and inlined at the use-site. Flexible: Using typeclass pattern, retroactively make types serializable NO BOILERPLATE: Typeclass instances generated at compile-time https://github.com/scala/pickling

Slide 26

Slide 26 text

Enter: Scala Pickling fast: Serialization code generated at compile- time and inlined at the use-site. Flexible: Using typeclass pattern, retroactively make types serializable NO BOILERPLATE: Typeclass instances generated at compile-time pluggable formats: Effortlessly change format of serialized data: binary, JSON, invent your own! https://github.com/scala/pickling

Slide 27

Slide 27 text

Enter: Scala Pickling fast: Serialization code generated at compile- time and inlined at the use-site. Flexible: Using typeclass pattern, retroactively make types serializable NO BOILERPLATE: Typeclass instances generated at compile-time pluggable formats: Effortlessly change format of serialized data: binary, JSON, invent your own! typesafe: Picklers are type-specialized. Catch errors at compile-time! https://github.com/scala/pickling

Slide 28

Slide 28 text

What does it look like? https://github.com/scala/pickling

Slide 29

Slide 29 text

What does it look like? scala>  import  scala.pickling._ import  scala.pickling._ https://github.com/scala/pickling

Slide 30

Slide 30 text

What does it look like? scala>  import  scala.pickling._ import  scala.pickling._ https://github.com/scala/pickling scala>  import  json._ import  json._

Slide 31

Slide 31 text

What does it look like? scala>  import  scala.pickling._ import  scala.pickling._ https://github.com/scala/pickling scala>  import  json._ import  json._ scala>  case  class  Person(name:  String,  age:  Int) defined  class  Person scala>  Person("John  Oliver",  36) res0:  Person  =  Person(John  Oliver,36)

Slide 32

Slide 32 text

What does it look like? scala>  import  scala.pickling._ import  scala.pickling._ https://github.com/scala/pickling scala>  import  json._ import  json._ scala>  case  class  Person(name:  String,  age:  Int) defined  class  Person scala>  Person("John  Oliver",  36) res0:  Person  =  Person(John  Oliver,36) scala>  res0.pickle res1:  scala.pickling.json.JSONPickle  =   JSONPickle({    "tpe":  "Person",    "name":  "John  Oliver",    "age":  36 })

Slide 33

Slide 33 text

and... it’s pretty fast https://github.com/scala/pickling

Slide 34

Slide 34 text

collections: Time Benchmarks

Slide 35

Slide 35 text

Benchmarks collections: free Memory (more is better)

Slide 36

Slide 36 text

Benchmarks collections: size

Slide 37

Slide 37 text

Benchmarks geotrellis: time

Slide 38

Slide 38 text

Benchmarks evactor: time Java runs out of memory

Slide 39

Slide 39 text

Benchmarks evactor: time (no java, more events)

Slide 40

Slide 40 text

that’s just the btw, default behavior... https://github.com/scala/pickling

Slide 41

Slide 41 text

that’s just the btw, default behavior... you can really customize scala pickling too. https://github.com/scala/pickling

Slide 42

Slide 42 text

Previous examples used default behavior Customizing Pickling Pickling is very customizable Before we can show these things,let's have a look at the building block of the framework... Generated picklers Standard pickle format Custom picklers for specific types Custom pickle format

Slide 43

Slide 43 text

Pickler Combinators trait  Pickler[T]  {    //  returns  next  write  position    def  pickle(arr:  Array[Byte],  i:  Int,  x:  T):  Int    //  returns  result  plus  next  read  position    def  unpickle(arr:  Array[Byte],  i:  Int):  (T,  Int) } Elegant programming pearl that comes from functional programming. A composable and "constructive" way to think about persisting data. Compose picklers for simple types to build picklers for more complicated types What is a pickler? simplified version of what’s actually used in scala- pickling https://github.com/scala/pickling

Slide 44

Slide 44 text

https://github.com/scala/pickling Pickler Combinators We need 2 things: fully-implemented picklers for some basic types like primitives 1 Picklers for base types Functions that combine existing picklers to build compound picklers 2 example: combinator that takes a Pickler[T] and returns a Pickler[List[T]]

Slide 45

Slide 45 text

Pickler Combinators Build a pickler for pairs (Int, String), combine an Int pickler and a String pickler val  myPairPickler  =  tuple2Pickler(intPickler,  stringPickler) What’s the type? Can we combine them automatically? Pickler[T], can pickle objects of type T def pickle(implicit pickler: Pickler[(Int, String)]) = { pickler.pickle((32, “yay!”)) } Goal: Can take intPickler and stringPickler as implicit parameters tuple2Pickler can be an implicit def https://github.com/scala/pickling

Slide 46

Slide 46 text

Implicit Picklers case  class  Person(name:  String,  age:  Int,  salary:  Int) class  CustomPersonPickler(implicit  val  format:  PickleFormat)  extends  SPickler[Person]  {    def  pickle(picklee:  Person,  builder:  PBuilder):  Unit  =  {        builder.beginEntry(picklee)        builder.putField("name",  b  =>            b.hintTag(FastTypeTag.ScalaString).beginEntry(picklee.name).endEntry())        builder.putField("age",  b  =>            b.hintTag(FastTypeTag.Int).beginEntry(picklee.age).endEntry())        builder.endEntry()    } } implicit  def  genCustomPersonPickler(implicit  format:  PickleFormat)  =    new  CustomPersonPickler customize what you pickle! https://github.com/scala/pickling

Slide 47

Slide 47 text

Pickle Format        trait  PickleFormat  {                type  PickleType  <:  Pickle                def  createBuilder():  PBuilder                def  createReader(pickle:  PickleType,  mirror:  Mirror):  PReader            }        trait  PBuilder  extends  Hintable  {            def  beginEntry(picklee:  Any):  this.type            def  putField(name:  String,  pickler:  this.type  =>  Unit):  this.type            def  endEntry():  Unit            def  beginCollection(length:  Int):  this.type            def  putElement(pickler:  this.type  =>  Unit):  this.type            def  endCollection(length:  Int):  Unit            def  result():  Pickle        } https://github.com/scala/pickling

Slide 48

Slide 48 text

Pickle Format output any format!        trait  PickleFormat  {                type  PickleType  <:  Pickle                def  createBuilder():  PBuilder                def  createReader(pickle:  PickleType,  mirror:  Mirror):  PReader            }        trait  PBuilder  extends  Hintable  {            def  beginEntry(picklee:  Any):  this.type            def  putField(name:  String,  pickler:  this.type  =>  Unit):  this.type            def  endEntry():  Unit            def  beginCollection(length:  Int):  this.type            def  putElement(pickler:  this.type  =>  Unit):  this.type            def  endCollection(length:  Int):  Unit            def  result():  Pickle        } https://github.com/scala/pickling

Slide 49

Slide 49 text

Pickle Format https://gist.github.com/heathermiller/5760171 example Output edn, Clojure’s data transfer format. toy builder implementation: scala>  import  scala.pickling._ import  scala.pickling._ scala>  import  edn._ import  edn._ scala>  case  class  Person(name:  String,  kidsAges:  Array[Int]) defined  class  Person scala>  val  joe  =  Person("Joe",  Array(3,  4,  13)) joe:  Person  =  Person(Joe,[I@3d925789) scala>  joe.pickle.value res0:  String  =  #pickling/Person  {  :name  "Joe"  :kidsAges  [3,  4,  13]  }

Slide 50

Slide 50 text

Pickle Format https://gist.github.com/heathermiller/5760171 example Output edn, Clojure’s data transfer format. talk to a clojure app toy builder implementation: scala>  import  scala.pickling._ import  scala.pickling._ scala>  import  edn._ import  edn._ scala>  case  class  Person(name:  String,  kidsAges:  Array[Int]) defined  class  Person scala>  val  joe  =  Person("Joe",  Array(3,  4,  13)) joe:  Person  =  Person(Joe,[I@3d925789) scala>  joe.pickle.value res0:  String  =  #pickling/Person  {  :name  "Joe"  :kidsAges  [3,  4,  13]  }

Slide 51

Slide 51 text

What can be pickled? if there is an implicit of type Pickler[Foo] in scope, you can pickle instances of it types for which an implicit pickler is in scope types for which our framework can generate picklers classes case classes generic classes singleton objects primitives & primitive arrays ... can’t (yet): instances of inner classes, Types https://github.com/scala/pickling

Slide 52

Slide 52 text

What can be pickled? if there is an implicit of type Pickler[Foo] in scope, you can pickle instances of it types for which an implicit pickler is in scope types for which our framework can generate picklers classes case classes generic classes singleton objects primitives & primitive arrays ... IMPORTANT: The implicit picklers are used in the generation! can’t (yet): instances of inner classes, Types https://github.com/scala/pickling

Slide 53

Slide 53 text

Status Release 0.8.0 for Scala 2.10.2 No support for inner classes, yet ScalaCheck tests Very soon: support for cyclic object graphs (for release 0.9.0) https://github.com/scala/pickling

Slide 54

Slide 54 text

Status Scala 2.11 as target Goal: Release 0.8.0 for Scala 2.10.2 No support for inner classes, yet ScalaCheck tests Very soon: support for cyclic object graphs (for release 0.9.0) https://github.com/scala/pickling

Slide 55

Slide 55 text

Status Scala 2.11 as target Goal: Plan: 1.0 release within the next few months SIP for Scala 2.11 Integration with sbt, Spark, and Akka, ... Experiment: use Scala-pickling to speed up Scala compiler Release 0.8.0 for Scala 2.10.2 No support for inner classes, yet ScalaCheck tests Very soon: support for cyclic object graphs (for release 0.9.0) https://github.com/scala/pickling

Slide 56

Slide 56 text

And now onto something completely different.

Slide 57

Slide 57 text

spores! scala http://docs.scala-lang.org/sips/pending/spores.html

Slide 58

Slide 58 text

What are they?

Slide 59

Slide 59 text

small units of mobile functional behavior What are they?

Slide 60

Slide 60 text

http://docs.scala-lang.org/sips/pending/spores.html proposed for inclusion in scala 2.11 small units of mobile functional behavior What are they?

Slide 61

Slide 61 text

First, some Motivation http://docs.scala-lang.org/sips/pending/spores.html

Slide 62

Slide 62 text

Motivation def  receive  =  {    case  Request(data)  =>        future  {            val  result  =  transform(data)            sender  !  Response(result)        } } Potential hazards when using closures incorrectly: • Memory leaks • Race conditions, due to capturing mutable references • Runtime serialization errors, due to unintended capture of references akka actor spawns a future to concurrently process incoming reqs not a stable value! http://docs.scala-lang.org/sips/pending/spores.html

Slide 63

Slide 63 text

Serialization case  class  Helper(name:  String) class  Main  {    val  helper  =  Helper("the  helper")    val  fun:  Int  =>  Unit  =  (x:  Int)  =>  {        val  result  =  x  +  "  "  +  helper.toString        println("The  result  is:  "  +  result)    } } Serialization of fun throws a NotSerializableException. Why? doesn’t extend serializable http://docs.scala-lang.org/sips/pending/spores.html

Slide 64

Slide 64 text

Spores val s = spore { val h = helper (x: Int) => { val result = x + " " + h.toString println("The result is: " + result) } } an alternative way to create closure-like objects, in a way where the environment is controlled

Slide 65

Slide 65 text

Spores val s = spore { val h = helper (x: Int) => { val result = x + " " + h.toString println("The result is: " + result) } } an alternative way to create closure-like objects, in a way where the environment is controlled The body of a spore consists of two parts: 1. a sequence of local value (val) declarations only, and 2.a closure.

Slide 66

Slide 66 text

Spores val s = spore { val h = helper (x: Int) => { val result = x + " " + h.toString println("The result is: " + result) } } an alternative way to create closure-like objects, in a way where the environment is controlled The body of a spore consists of two parts: 1. a sequence of local value (val) declarations only, and 2.a closure. The closure of a spore has to satisfy the following rule. All free variables of the closure body have to be either 1. parameters of the closure, or 2.declared in the preceding sequence of local value declarations.

Slide 67

Slide 67 text

Inspiration Spores are not limited to distributed programming Make your APIs safer by expecting a Spore instead of a function By requiring spores in your public APIs you can prevent users from introducing hazards, like race conditions. Make your users more happy by preventing them from shooting themselves in the foot! do you have state & asynchrony? http://docs.scala-lang.org/sips/pending/spores.html

Slide 68

Slide 68 text

Status SIP-21 Spores: on docs.scala-lang.org/sips now! Get involved in the discussion! Pull request for Scala 2.11 and Akka 2.2.1 in preparation Integration with Scala-pickling planned http://docs.scala-lang.org/sips/pending/spores.html

Slide 69

Slide 69 text

qUESTIONS ? heather.miller@epfl.ch @heathercmiller Contact