SlideShare una empresa de Scribd logo
1 de 32
Whereobjects and functionsmeet by Mario Fusco mario.fusco@gmail.com twitter: @mariofusco
day 1:    hour 1: Object Orientation        Classes, Objects and Traits        Generic Types        Case Classes, Patter Matching and Tuples    hour 2: Functional Programming        First-class and Anonymous Functions  Higer-Order Functions and Curry        Implicit Parameters and Conversions        Using Scala features to create a simple DSLday 2:    hour 1: Using OO and FP together        Structural Typing        Scala Collections        For-Comprehensions        Options and Monads    hour 2: Concurrency        Abstractions for Concurrency        Actors and Remote Actors
Do we need a new language? Keep It Simple Vs. Do More With Less
statically typed object-oriented functional scriptable Why Scala? concise Java compatible extensible concurrent
The first Scala class class Rational(n: Int, d: Int) { valnum = n val den = d defthis(n: Int) = this(n, 1) def + (that: Rational): Rational = new Rational(num * that.den + that.num * den, den * that.den) def + (i: Int): Rational = new Rational(num + i * den, den) overridedeftoString = "" + num + "/" + den }
Named and default parameters classRational(n: Int= 1, d: Int = 1) extendsAnyRef {  .... } Rational(n = 2, d = 3) Rational(d = 3, n = 2) Rational(d = 3) Rational()
Scala’s type hierarchy
Object (Companion) objectRationalOneextends Rational(1) object Rational { def apply(n: Int) = new Rational(n) def apply(n: Int, d: Int) = new Rational(n, d) } valone = RationalOne valtwo = Rational(1) + one  val two = Rational(1).+(one)
Traits classAnimal                  { defeat(): Unit } traitMammalextendsAnimal   { defgiveBirth(): Mammal } traitHasWingsextendsAnimal { deffly(): Unit } traitHasLegsextendsAnimal  { defwalk(): Unit } class Snake extendsAnimal classFrogextendsAnimal with HasLegs classCatextendsAnimalwithMammalwithHasLegs classBatextendsAnimalwithMammalwithHasWings class Chimera extendsAnimalwithMammalwithHasWingswithHasLegs
Let’s put alltogether trait IntSet { defcontains(x: Int): Boolean defnotContains(x: A) = !contains(x) defadd(x: Int): IntSet } object EmptySetextends IntSet { defcontains(x: Int): Boolean = false defadd(x: Int): IntSet = new NonEmptySet(x, EmptySet, EmptySet) } class NonEmptySet(elem: Int, left: IntSet, right: IntSet) extends IntSet{ defcontains(x: Int): Boolean =     if (x < elem) left contains x     else if (x > elem) right contains x     else true defadd(x: Int): IntSet =     if (x < elem) new NonEmptySet(elem, left add x, right)     else if (x > elem) new NonEmptySet(elem, left, right add x)     else this }
GenericTypes trait Set[A <: Ordered[A]] { def contains(x: A): Boolean def add(x: A): Set[A] } classEmptySet[A <: Ordered[A]] extends Set[A] { def contains(x: A): Boolean = false def add(x: A): Set[A] =     new NonEmptySet(x, newEmptySet[A], newEmptySet[A]) } classNonEmptySet[A <: Ordered[A]]                 (elem: A, left: Set[A], right: Set[A]) extends Set[A] { def contains(x: A): Boolean = if (x < elem) left contains x else if (x > elem) right contains x elsetrue def add(x: A): Set[A] = if (x < elem) newNonEmptySet(elem, left add x, right) elseif (x > elem) newNonEmptySet(elem, left, right add x) elsethis }
Case classes sealed traitExpr case class Var(name: String) extendsExpr case class Number(num: Double) extendsExpr case class Unop(op: String, arg: Expr) extendsExpr case class Binop(op: String, l: Expr, r: Expr) extendsExpr
Pattern matching def simplify(expr: Expr): Expr = exprmatch { caseUnop("-", Unop("-", e)) => e   // Double negation caseBinop("+", e, Number(0)) => e  // Adding zero caseBinop("*", e, Number(1)) => e  // Multiplying by one case _ => expr } // Simplify double negation: simplified = Var("x") val simplified = simplify(Unop("-", Unop("-", Var("x"))))
Tuples valpair = (2, "items") println(pair._1) // prints 2 println(pair._2) // printsitems defdivmod(x: Int, y: Int): (Int, Int) = (x / y, x % y) divmod(x, y) match { case (n, d) => println("quotient: " + n + ", rest: " + d) }
defsumInts(a: Int, b: Int): Int = if (a > b) 0 else a + sumInts(a + 1, b) defsumSquares(a: Int, b: Int): Int=   if (a > b) 0 else a * a + sumSquares(a + 1, b) First-Class Function defsum(f: Int => Int, a: Int, b: Int): Int=   if (a > b) 0 else f(a) + sum(f, a + 1, b) defid(x: Int): Int = x defsumInts(a: Int, b: Int): Int = sum(id, a, b) defsquare(x: Int): Int = x * x defsumSquares(a: Int, b: Int): Int = sum(square, a, b) Anonymous Function defsumInts(a: Int, b: Int): Int = sum((x: Int) => x, a, b) defsumSquares(a: Int, b: Int): Int = sum((x: Int) => x * x, a, b)
Higher-Order Functions and Curry defsum(f: Int => Int): (Int, Int) => Int = { defsumF(a: Int, b: Int): Int= if(a > b) 0 else f(a) + sumF(a + 1, b) sumF } defsumInts = sum(x => x) defsumSquares= sum(x => x * x) val sum1To10 = sumInts(1, 10) valsum1To10 = sum(x => x)(1, 10) def sum(f: Int => Int)(a: Int, b: Int): Int= if (a > b) 0 else f(a) + sum(f)(a + 1, b) def sum(a: Int, b: Int)(f: Int => Int): Int =  if(a > b) 0 else f(a) + sum(a + 1, b)(f) valsum1To10 = sum(1, 10) {   x => x  }
Implicitparameters abstractclassAggregator[A] { defunit: A defadd(x: A, y: A): A } objectstringAggregatorextendsAggregator[String] { defunit= "" defadd(x: String, y: String): String = x concaty } objectintAggregatorextendsAggregator[Int] { defunit= 0 defadd(x: Int, y: Int): Int= x + y } def sum[A](l: List[A]) (a: Aggregator[A]): A = if (l.isEmpty) a.unitelsea.add(l.head, sum(l.tail)(a)) sum(List("a", "b", "c"))(stringAggregator) sum(List(1, 2, 3))(intAggregator) (implicit a: Aggregator[A]): A =
Implicitconversion val a = new Rational(2, 3) val b = a + 2     // = 8/3 val c = 2 + a     // Compilation Error implicitdefintToRational(x: Int) = newRational(x) valc = 2 + a      // = 8/3 Viewbound traitSet[A <% Rational]
Duck typing is the dynamic mechanism that allows to discover a dog cannot say quack only at runtime ... in production ... on friday evening Structural Typing (duck typing done right) doQuack(d) { d.quack() } defdoQuack(d:{ def quack():Unit }) = d.quack() classDuck {  quack() { println "quack" }  } doQuack(new Duck) classDuck {  defquack() = println "quack"  } doQuack(new Duck) class Dog {  barf() { println "barf" }  } doQuack(new Dog) class Dog {  defbarf() = println "barf"  } doQuack(new Dog) compilation error runtime error
Lists valletters: List[String] = List("a", "b", "c", "d") valemptyList = Nil valletters= "a" :: "b" :: "c" :: "d" :: Nil x :: ysisequivalent to  ys.::(x) // infix operator == right associative xs ::: ysisequivalent toys.:::(xs) letters.head = "a" letters.tail = List("b", "c", "d") defsortedInsert(x: Int, xs: List[Int]): List[Int] = xsmatch { case List() => List(x) case y :: ys => if (x <= y) x :: xselse y :: sortedInsert(x, ys) }
Higher-Order Functions on Lists valanimals = List("dog", "cat", "horse", "rabbit") animals.foreach(s => println(s)) defforeach(f: A => Unit) { thismatch { caseNil => () case x :: xs => f(x); xs.foreach(f)   } } animals.foreach(println_) animals.foreach(println) animals.map(s => s + "s") animals.mkString(", ") animals.count(s => s.length > 3) animals.remove(s => s.length > 3) animals.sort((s,t) => s.charAt(1) < t.charAt(1)) animals.foldLeft(0)((s,t) => s + t.length) (0 /: animals)(_ + _.length)
For-Comprehensions for (p <- personsifp.age > 20) yield p.name personsfilter (p => p.age > 20) map (p => p.name) for {   p <- persons			// Generators   c <- p.children if c.name startsWith"A" 	// Filter } yield p.name			// Map
Given n>0 findallpairs iand j where 1 ≤j ≤ i ≤ n and i+jis prime List.range(1, n)   .map(i => List.range(1, i).map(x => (i, x)))   .foldRight(List[(Int, Int)]()) {(xs, ys) => xs ::: ys}   .filter(pair => isPrime(pair._1 + pair._2)) List.range(1, n)   .flatMap(i => List.range(1, i).map(x => (i, x)))   .filter(pair => isPrime(pair._1 + pair._2)) Where: class List[A] { defflatMap[B](f: A => List[B]): List[B] } for { i <- List.range(1, n)       j <- List.range(1, i)       if isPrime(i + j) } yield {i, j} List.range(1, n)   .flatMap(i => List.range(1, i)        .filter(j => isPrime(i+j))        .map(j => (i, j)))
Tony Hoare, who invented the null reference in 1965 while working on an object oriented language called ALGOL W, called its invention his “billion dollar mistake” Options valcapitals = Map("Italy" -> "Rome", "Switzerland" -> "Bern",                     "Germany" -> "Berlin" , "France" -> "Paris") println(capitals.get("Italy"))  // Some(Rome) println(capitals.get("Spain"))  // None println(capitals.get("Italy").get)  // Rome println(capitals.get("Spain").get)  // thorwsException println(capitals.get("Spain").getOrElse("Unknown"))  // Unknown
OptionsasMonads defmap[B](f: A => B): M[B] defflatMap[B](f: A => M[B]): M[B] deffilter(p: A => Boolean): M[A] defreadPositiveIntParam(params: Map[String, String], name: String): Int=  paramsgetnameflatMapstringToIntfilter (_ > 0) getOrElse 0 defstringToInt(string: String) : Option[Int] = try {   Some(string.toInt) } catch {   case _ : java.lang.NumberFormatException => None } defreadPositiveIntParam(params: Map[String, String], name: String): Int =   (for{ param<- paramsgetname;  value<- stringToInt(param) if (value > 0)   } yieldvalue) getOrElse 0 valparams = Map("a" -> "5", "b" -> "false", "c" -> "-3") valreadPositiveIntParam(params, "a") // == 5 valreadPositiveIntParam(params, "b") // == 0 – Samefor "c" and "d"
Signals and Monitors defsynchronized[A] (e: => A): A defwait() defwait(msec: Long) defnotify() defnotifyAll() SyncVar class SyncVar[A] {   private var isDefined: Boolean = false   private varvalue: A = _ defget = synchronized {     while (!isDefined) wait()     value   } defset(x: A) = synchronized {     value = x; isDefined = true; notifyAll()   } defisSet: Boolean = synchronized { isDefined } defunset = synchronized { isDefined= false } }
Futures deffuture[A](p: => A): Unit => A = { valresult = new SyncVar[A]   fork { result.set(p) }   (() => result.get) } valx = future(someLengthyComputation) anotherLengthyComputation valy = f(x()) + g(x()) Semaphores class Lock { varavailable = true defacquire = synchronized {     while (!available) wait()     available = false   } defrelease = synchronized {     available = true     notify()   } } Mailboxes class MailBox { defsend(msg: Any) defreceive[A](f: PartialFunction[Any, A]): A defreceiveWithin[A](msec: Long)(f: PartialFunction[Any, A]): A }
Actors classPrinterActorextendsActor { defact() { while(true) {   receive { casemsg=> println("Received message: " + msg)       }     }  } } valprinterActor = newPrinterActor printerActor.start printerActor! "hi there“  // prints "Received message: hi there" printerActor ! 23          // prints "Received message: 23"
Creating Actors with the actormethod importscala.actors.Actor._ valprinterActor = actor { while(true) {     receive { case s: String => println("I got a String: " + s) case i: Int => println("I got an Int: " + i.toString) case _ => println(" I don’t know what I got ")     }   } } printerActor ! "hi there"  // prints “I got a String: hi there” printerActor ! 23          // prints “I got an Int: 23” printerActor ! 3.33        // prints “I don’t know what I got”
reactinstead of receive (whenpossible) importscala.actors.Actor._ valprinterActor = actor {   loop { react { case s: String => println("I got a String: " + s) case i: Int => { println("I got an Int: " + i.toString) println(“Waiting for another Int") react { case j: Int=> println(“Another Int: " + j.toString)        }      } case _ => exit     }   } }
Message types ! send an asynchronous message which means that the sending actor does not wait until the message is received; its execution continues immediately. All actors have a mailbox which buffers incoming messages until they are processed !? senda synchronous message: causes the sending actor to wait until a response is received which is then returned. There is an overloaded variant taking a timeout and returning an Option[Any] instead of Any !! similar to !? In the sensethatitallows to get an answer from the receiver. However, instead of blocking the sending actor until a response is received, it returns Future instance that can be used to retrieve the receiver’s response once it is available
Remote Actors actor { // SERVER ACTOR RemoteActor.classLoader = getClass().getClassLoader()   alive(9000) // starts remote actor listening on the given port   register('Server, self) // registers the actor using the symbol loop { receive {case Message => sender ! ... }   } }  actor { // CLIENT ACTOR trapExit= true         // listens exit of linked actors RemoteActor.classLoader= getClass().getClassLoader() alive(9001) valserver = select(Node("127.0.0.1", 9000), 'Server)  link(server)           // linksthisactor to the server one  server ! Message       // sends a Message to the server }

Más contenido relacionado

La actualidad más candente

The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...John De Goes
 
Demystifying functional programming with Scala
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with ScalaDenis
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlinintelliyole
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Chris Richardson
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018John De Goes
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 
Let's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java APILet's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java APIMario Fusco
 
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей КоваленкоFwdays
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final TaglessJohn De Goes
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them AllJohn De Goes
 
Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015Leonardo Borges
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsJohn De Goes
 
Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()daewon jeong
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In JavaAndrei Solntsev
 

La actualidad más candente (20)

Sneaking inside Kotlin features
Sneaking inside Kotlin featuresSneaking inside Kotlin features
Sneaking inside Kotlin features
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
 
Demystifying functional programming with Scala
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with Scala
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlin
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Let's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java APILet's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java API
 
Kotlin, why?
Kotlin, why?Kotlin, why?
Kotlin, why?
 
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко"Немного о функциональном программирование в JavaScript" Алексей Коваленко
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
 
Comparing JVM languages
Comparing JVM languagesComparing JVM languages
Comparing JVM languages
 
What's New In C# 7
What's New In C# 7What's New In C# 7
What's New In C# 7
 
Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
 

Destacado

If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongMario Fusco
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Mario Fusco
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Mario Fusco
 
Comparing different concurrency models on the JVM
Comparing different concurrency models on the JVMComparing different concurrency models on the JVM
Comparing different concurrency models on the JVMMario Fusco
 
Drools 6 deep dive
Drools 6 deep diveDrools 6 deep dive
Drools 6 deep diveMario Fusco
 
Why we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingMario Fusco
 
Real world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageReal world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageMario Fusco
 
Swiss army knife Spring
Swiss army knife SpringSwiss army knife Spring
Swiss army knife SpringMario Fusco
 
Introducing Drools
Introducing DroolsIntroducing Drools
Introducing DroolsMario Fusco
 
No more loops with lambdaj
No more loops with lambdajNo more loops with lambdaj
No more loops with lambdajMario Fusco
 

Destacado (12)

If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are Wrong
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
 
Comparing different concurrency models on the JVM
Comparing different concurrency models on the JVMComparing different concurrency models on the JVM
Comparing different concurrency models on the JVM
 
Monadic Java
Monadic JavaMonadic Java
Monadic Java
 
Drools 6 deep dive
Drools 6 deep diveDrools 6 deep dive
Drools 6 deep dive
 
Why we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional Programming
 
Real world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageReal world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same language
 
Seven Deadly Sins
Seven Deadly Sins Seven Deadly Sins
Seven Deadly Sins
 
Swiss army knife Spring
Swiss army knife SpringSwiss army knife Spring
Swiss army knife Spring
 
Introducing Drools
Introducing DroolsIntroducing Drools
Introducing Drools
 
No more loops with lambdaj
No more loops with lambdajNo more loops with lambdaj
No more loops with lambdaj
 

Similar a Scala - where objects and functions meet

JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersTikal Knowledge
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming iiPrashant Kalkar
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecLoïc Descotte
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2Hang Zhao
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaDaniel Sebban
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala Knoldus Inc.
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
Swift the implicit parts
Swift the implicit partsSwift the implicit parts
Swift the implicit partsMaxim Zaks
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009David Pollak
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scalaparag978978
 
FP in scalaで鍛える関数型脳
FP in scalaで鍛える関数型脳FP in scalaで鍛える関数型脳
FP in scalaで鍛える関数型脳Yuri Inoue
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOJorge Vásquez
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In ScalaSkills Matter
 

Similar a Scala - where objects and functions meet (20)

SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java Programmers
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Meet scala
Meet scalaMeet scala
Meet scala
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
Scalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with ScalaScalapeno18 - Thinking Less with Scala
Scalapeno18 - Thinking Less with Scala
 
Scala best practices
Scala best practicesScala best practices
Scala best practices
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
An introduction to scala
An introduction to scalaAn introduction to scala
An introduction to scala
 
Monadologie
MonadologieMonadologie
Monadologie
 
Swift the implicit parts
Swift the implicit partsSwift the implicit parts
Swift the implicit parts
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scala
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
FP in scalaで鍛える関数型脳
FP in scalaで鍛える関数型脳FP in scalaで鍛える関数型脳
FP in scalaで鍛える関数型脳
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIO
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In Scala
 

Scala - where objects and functions meet

  • 1. Whereobjects and functionsmeet by Mario Fusco mario.fusco@gmail.com twitter: @mariofusco
  • 2. day 1:    hour 1: Object Orientation        Classes, Objects and Traits        Generic Types        Case Classes, Patter Matching and Tuples    hour 2: Functional Programming        First-class and Anonymous Functions Higer-Order Functions and Curry        Implicit Parameters and Conversions        Using Scala features to create a simple DSLday 2:    hour 1: Using OO and FP together        Structural Typing        Scala Collections        For-Comprehensions        Options and Monads    hour 2: Concurrency        Abstractions for Concurrency        Actors and Remote Actors
  • 3. Do we need a new language? Keep It Simple Vs. Do More With Less
  • 4. statically typed object-oriented functional scriptable Why Scala? concise Java compatible extensible concurrent
  • 5. The first Scala class class Rational(n: Int, d: Int) { valnum = n val den = d defthis(n: Int) = this(n, 1) def + (that: Rational): Rational = new Rational(num * that.den + that.num * den, den * that.den) def + (i: Int): Rational = new Rational(num + i * den, den) overridedeftoString = "" + num + "/" + den }
  • 6. Named and default parameters classRational(n: Int= 1, d: Int = 1) extendsAnyRef { .... } Rational(n = 2, d = 3) Rational(d = 3, n = 2) Rational(d = 3) Rational()
  • 8. Object (Companion) objectRationalOneextends Rational(1) object Rational { def apply(n: Int) = new Rational(n) def apply(n: Int, d: Int) = new Rational(n, d) } valone = RationalOne valtwo = Rational(1) + one val two = Rational(1).+(one)
  • 9. Traits classAnimal { defeat(): Unit } traitMammalextendsAnimal { defgiveBirth(): Mammal } traitHasWingsextendsAnimal { deffly(): Unit } traitHasLegsextendsAnimal { defwalk(): Unit } class Snake extendsAnimal classFrogextendsAnimal with HasLegs classCatextendsAnimalwithMammalwithHasLegs classBatextendsAnimalwithMammalwithHasWings class Chimera extendsAnimalwithMammalwithHasWingswithHasLegs
  • 10. Let’s put alltogether trait IntSet { defcontains(x: Int): Boolean defnotContains(x: A) = !contains(x) defadd(x: Int): IntSet } object EmptySetextends IntSet { defcontains(x: Int): Boolean = false defadd(x: Int): IntSet = new NonEmptySet(x, EmptySet, EmptySet) } class NonEmptySet(elem: Int, left: IntSet, right: IntSet) extends IntSet{ defcontains(x: Int): Boolean = if (x < elem) left contains x else if (x > elem) right contains x else true defadd(x: Int): IntSet = if (x < elem) new NonEmptySet(elem, left add x, right) else if (x > elem) new NonEmptySet(elem, left, right add x) else this }
  • 11. GenericTypes trait Set[A <: Ordered[A]] { def contains(x: A): Boolean def add(x: A): Set[A] } classEmptySet[A <: Ordered[A]] extends Set[A] { def contains(x: A): Boolean = false def add(x: A): Set[A] = new NonEmptySet(x, newEmptySet[A], newEmptySet[A]) } classNonEmptySet[A <: Ordered[A]] (elem: A, left: Set[A], right: Set[A]) extends Set[A] { def contains(x: A): Boolean = if (x < elem) left contains x else if (x > elem) right contains x elsetrue def add(x: A): Set[A] = if (x < elem) newNonEmptySet(elem, left add x, right) elseif (x > elem) newNonEmptySet(elem, left, right add x) elsethis }
  • 12. Case classes sealed traitExpr case class Var(name: String) extendsExpr case class Number(num: Double) extendsExpr case class Unop(op: String, arg: Expr) extendsExpr case class Binop(op: String, l: Expr, r: Expr) extendsExpr
  • 13. Pattern matching def simplify(expr: Expr): Expr = exprmatch { caseUnop("-", Unop("-", e)) => e // Double negation caseBinop("+", e, Number(0)) => e // Adding zero caseBinop("*", e, Number(1)) => e // Multiplying by one case _ => expr } // Simplify double negation: simplified = Var("x") val simplified = simplify(Unop("-", Unop("-", Var("x"))))
  • 14. Tuples valpair = (2, "items") println(pair._1) // prints 2 println(pair._2) // printsitems defdivmod(x: Int, y: Int): (Int, Int) = (x / y, x % y) divmod(x, y) match { case (n, d) => println("quotient: " + n + ", rest: " + d) }
  • 15. defsumInts(a: Int, b: Int): Int = if (a > b) 0 else a + sumInts(a + 1, b) defsumSquares(a: Int, b: Int): Int= if (a > b) 0 else a * a + sumSquares(a + 1, b) First-Class Function defsum(f: Int => Int, a: Int, b: Int): Int= if (a > b) 0 else f(a) + sum(f, a + 1, b) defid(x: Int): Int = x defsumInts(a: Int, b: Int): Int = sum(id, a, b) defsquare(x: Int): Int = x * x defsumSquares(a: Int, b: Int): Int = sum(square, a, b) Anonymous Function defsumInts(a: Int, b: Int): Int = sum((x: Int) => x, a, b) defsumSquares(a: Int, b: Int): Int = sum((x: Int) => x * x, a, b)
  • 16. Higher-Order Functions and Curry defsum(f: Int => Int): (Int, Int) => Int = { defsumF(a: Int, b: Int): Int= if(a > b) 0 else f(a) + sumF(a + 1, b) sumF } defsumInts = sum(x => x) defsumSquares= sum(x => x * x) val sum1To10 = sumInts(1, 10) valsum1To10 = sum(x => x)(1, 10) def sum(f: Int => Int)(a: Int, b: Int): Int= if (a > b) 0 else f(a) + sum(f)(a + 1, b) def sum(a: Int, b: Int)(f: Int => Int): Int = if(a > b) 0 else f(a) + sum(a + 1, b)(f) valsum1To10 = sum(1, 10) { x => x }
  • 17. Implicitparameters abstractclassAggregator[A] { defunit: A defadd(x: A, y: A): A } objectstringAggregatorextendsAggregator[String] { defunit= "" defadd(x: String, y: String): String = x concaty } objectintAggregatorextendsAggregator[Int] { defunit= 0 defadd(x: Int, y: Int): Int= x + y } def sum[A](l: List[A]) (a: Aggregator[A]): A = if (l.isEmpty) a.unitelsea.add(l.head, sum(l.tail)(a)) sum(List("a", "b", "c"))(stringAggregator) sum(List(1, 2, 3))(intAggregator) (implicit a: Aggregator[A]): A =
  • 18. Implicitconversion val a = new Rational(2, 3) val b = a + 2 // = 8/3 val c = 2 + a // Compilation Error implicitdefintToRational(x: Int) = newRational(x) valc = 2 + a // = 8/3 Viewbound traitSet[A <% Rational]
  • 19. Duck typing is the dynamic mechanism that allows to discover a dog cannot say quack only at runtime ... in production ... on friday evening Structural Typing (duck typing done right) doQuack(d) { d.quack() } defdoQuack(d:{ def quack():Unit }) = d.quack() classDuck { quack() { println "quack" } } doQuack(new Duck) classDuck { defquack() = println "quack" } doQuack(new Duck) class Dog { barf() { println "barf" } } doQuack(new Dog) class Dog { defbarf() = println "barf" } doQuack(new Dog) compilation error runtime error
  • 20. Lists valletters: List[String] = List("a", "b", "c", "d") valemptyList = Nil valletters= "a" :: "b" :: "c" :: "d" :: Nil x :: ysisequivalent to ys.::(x) // infix operator == right associative xs ::: ysisequivalent toys.:::(xs) letters.head = "a" letters.tail = List("b", "c", "d") defsortedInsert(x: Int, xs: List[Int]): List[Int] = xsmatch { case List() => List(x) case y :: ys => if (x <= y) x :: xselse y :: sortedInsert(x, ys) }
  • 21. Higher-Order Functions on Lists valanimals = List("dog", "cat", "horse", "rabbit") animals.foreach(s => println(s)) defforeach(f: A => Unit) { thismatch { caseNil => () case x :: xs => f(x); xs.foreach(f) } } animals.foreach(println_) animals.foreach(println) animals.map(s => s + "s") animals.mkString(", ") animals.count(s => s.length > 3) animals.remove(s => s.length > 3) animals.sort((s,t) => s.charAt(1) < t.charAt(1)) animals.foldLeft(0)((s,t) => s + t.length) (0 /: animals)(_ + _.length)
  • 22. For-Comprehensions for (p <- personsifp.age > 20) yield p.name personsfilter (p => p.age > 20) map (p => p.name) for { p <- persons // Generators c <- p.children if c.name startsWith"A" // Filter } yield p.name // Map
  • 23. Given n>0 findallpairs iand j where 1 ≤j ≤ i ≤ n and i+jis prime List.range(1, n) .map(i => List.range(1, i).map(x => (i, x))) .foldRight(List[(Int, Int)]()) {(xs, ys) => xs ::: ys} .filter(pair => isPrime(pair._1 + pair._2)) List.range(1, n) .flatMap(i => List.range(1, i).map(x => (i, x))) .filter(pair => isPrime(pair._1 + pair._2)) Where: class List[A] { defflatMap[B](f: A => List[B]): List[B] } for { i <- List.range(1, n) j <- List.range(1, i) if isPrime(i + j) } yield {i, j} List.range(1, n) .flatMap(i => List.range(1, i) .filter(j => isPrime(i+j)) .map(j => (i, j)))
  • 24. Tony Hoare, who invented the null reference in 1965 while working on an object oriented language called ALGOL W, called its invention his “billion dollar mistake” Options valcapitals = Map("Italy" -> "Rome", "Switzerland" -> "Bern", "Germany" -> "Berlin" , "France" -> "Paris") println(capitals.get("Italy")) // Some(Rome) println(capitals.get("Spain")) // None println(capitals.get("Italy").get) // Rome println(capitals.get("Spain").get) // thorwsException println(capitals.get("Spain").getOrElse("Unknown")) // Unknown
  • 25. OptionsasMonads defmap[B](f: A => B): M[B] defflatMap[B](f: A => M[B]): M[B] deffilter(p: A => Boolean): M[A] defreadPositiveIntParam(params: Map[String, String], name: String): Int= paramsgetnameflatMapstringToIntfilter (_ > 0) getOrElse 0 defstringToInt(string: String) : Option[Int] = try { Some(string.toInt) } catch { case _ : java.lang.NumberFormatException => None } defreadPositiveIntParam(params: Map[String, String], name: String): Int = (for{ param<- paramsgetname; value<- stringToInt(param) if (value > 0) } yieldvalue) getOrElse 0 valparams = Map("a" -> "5", "b" -> "false", "c" -> "-3") valreadPositiveIntParam(params, "a") // == 5 valreadPositiveIntParam(params, "b") // == 0 – Samefor "c" and "d"
  • 26. Signals and Monitors defsynchronized[A] (e: => A): A defwait() defwait(msec: Long) defnotify() defnotifyAll() SyncVar class SyncVar[A] { private var isDefined: Boolean = false private varvalue: A = _ defget = synchronized { while (!isDefined) wait() value } defset(x: A) = synchronized { value = x; isDefined = true; notifyAll() } defisSet: Boolean = synchronized { isDefined } defunset = synchronized { isDefined= false } }
  • 27. Futures deffuture[A](p: => A): Unit => A = { valresult = new SyncVar[A] fork { result.set(p) } (() => result.get) } valx = future(someLengthyComputation) anotherLengthyComputation valy = f(x()) + g(x()) Semaphores class Lock { varavailable = true defacquire = synchronized { while (!available) wait() available = false } defrelease = synchronized { available = true notify() } } Mailboxes class MailBox { defsend(msg: Any) defreceive[A](f: PartialFunction[Any, A]): A defreceiveWithin[A](msec: Long)(f: PartialFunction[Any, A]): A }
  • 28. Actors classPrinterActorextendsActor { defact() { while(true) { receive { casemsg=> println("Received message: " + msg) } } } } valprinterActor = newPrinterActor printerActor.start printerActor! "hi there“ // prints "Received message: hi there" printerActor ! 23 // prints "Received message: 23"
  • 29. Creating Actors with the actormethod importscala.actors.Actor._ valprinterActor = actor { while(true) { receive { case s: String => println("I got a String: " + s) case i: Int => println("I got an Int: " + i.toString) case _ => println(" I don’t know what I got ") } } } printerActor ! "hi there" // prints “I got a String: hi there” printerActor ! 23 // prints “I got an Int: 23” printerActor ! 3.33 // prints “I don’t know what I got”
  • 30. reactinstead of receive (whenpossible) importscala.actors.Actor._ valprinterActor = actor { loop { react { case s: String => println("I got a String: " + s) case i: Int => { println("I got an Int: " + i.toString) println(“Waiting for another Int") react { case j: Int=> println(“Another Int: " + j.toString) } } case _ => exit } } }
  • 31. Message types ! send an asynchronous message which means that the sending actor does not wait until the message is received; its execution continues immediately. All actors have a mailbox which buffers incoming messages until they are processed !? senda synchronous message: causes the sending actor to wait until a response is received which is then returned. There is an overloaded variant taking a timeout and returning an Option[Any] instead of Any !! similar to !? In the sensethatitallows to get an answer from the receiver. However, instead of blocking the sending actor until a response is received, it returns Future instance that can be used to retrieve the receiver’s response once it is available
  • 32. Remote Actors actor { // SERVER ACTOR RemoteActor.classLoader = getClass().getClassLoader() alive(9000) // starts remote actor listening on the given port register('Server, self) // registers the actor using the symbol loop { receive {case Message => sender ! ... } } } actor { // CLIENT ACTOR trapExit= true // listens exit of linked actors RemoteActor.classLoader= getClass().getClassLoader() alive(9001) valserver = select(Node("127.0.0.1", 9000), 'Server) link(server) // linksthisactor to the server one server ! Message // sends a Message to the server }