Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Intro to Scala + Higher Order Functions

Intro to Scala + Higher Order Functions

A remix combining the Intro to Scala and HOF's talks for the Sept'13 @betabeersSVQ

Raúl Raja Martínez

September 17, 2013
Tweet

More Decks by Raúl Raja Martínez

Other Decks in Programming

Transcript

  1. WHO USES SCALA? /47 DEGREES AND... H SBC KLO U

    T LIN KEDIN LIVIN G SO C IAL Q U O RA REM EM BER TH E M ILK SEESM IC STAC KM O B TW ITTER TU M BLR VM W ARE YAM M ER N O VEL AO L BO X E-H ARM O N Y http://www.quora.com/Startups/What-startups-or-tech-companies-are-using-Scala
  2. SCALA FEATURES /JUST A FEW... High Order functions and great

    support for map, flatmap, tabulate, filter, foreach... Traits, classes, case classes, object... Attach behaviors at runtime. new Foo with Other Flexible syntax, create constructs, infix support, everything is a value val test = if(...) val collection = for(...) Emphasis on immutable data structures. Transformations and copies vs state Built in support for this high concurrency pattern IMMUTABILITY EMPHASIS FUNCTIONAL OOP ACTORS MIXINS IDIOMATIC
  3. IMMUTABILITY In Java we tend to use Mutable structures that

    need synchronization JAVA List<Integer> even = new ArrayList<Integer>(); for (String num : numbersAsStrings) { int parsedInt = Integer.parseInt(num); if (parsedInt % 2 == 0) { ints.add(parsedInt); } } In Scala we transform values into new values SCALA val ints = for (num <- numbersAsStrings; if num.toInt % 2 == 0) yield num.toInt No need to synchronize in structures which state is never modified
  4. FUNCTIONAL In Scala everything returns a value scala> val myInt

    = 1 myInt: Int = 1 scala> def myFunction = "I don't need a return" myFunction: String scala> val result = for (n <- 0 to 10) yield n result: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) scala> val ifAreValues2 = if (true) "test" ifAreValues2: Any = test scala> val ifAreValues3 = if (true) "test" else "test2" ifAreValues3: String = test Functional style encourages to pipe the results of functions and operations Vs Imperative style Iterator.continually(Option(queue.poll(1, TimeUnit.SECONDS))).takeWhile(_ => running) foreach { msg => write(msg) }
  5. OOP In Scala everything is an Object and supports a

    richer object model than Java ( multiple inheritance? :) ) Traits trait Similarity { def isSimilar(x: Any): Boolean def isNotSimilar(x: Any): Boolean = !isSimilar(x) } Classes class Point(xc: Int, yc: Int) extends Similarity { var x: Int = xc var y: Int = yc def isSimilar(obj: Any) = obj.isInstanceOf[Point] && obj.asInstanceOf[Point].x == x } Case Classes case class Point(xc: Int, yc: Int) extends Similarity { def isSimilar(obj: Any) = obj.isInstanceOf[Point] && obj.asInstanceOf[Point].x == x } Objects (singletons) object TraitsTest { val p1 = Point(2, 3) val p2 = Point(2, 4) val p3 = Point(3, 3) println(p1.isNotSimilar(p2)) println(p1.isNotSimilar(p3)) println(p1.isNotSimilar(2)) }
  6. ACTORS Use actors for a high concurrent fault tolerant distributed

    messaging system /** invoke your army **/ val emailServiceActor = Akka.system.actorOf( Props[EmailServiceActor].withRouter( SmallestMailboxRouter(nrOfInstances = 50) ), name = "emailService" ) /** send him to war **/ emailServiceActor ! emailMessage /** this is the guy overseeing everything in the pentagon **/ class EmailServiceActor extends Actor{ override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10) { case emailException: EmailException => Restart case unknownCase: Any => Stop } def receive = { case message: Any => context.actorOf(Props[EmailServiceWorker]) ! message } } /** And this one is the one in the field **/ class EmailServiceWorker extends Actor{ /** And this one is the one in the field **/ private var emailMessage: Option[EmailMessage] = None def receive = { case Some(email): EmailMessage => { email.deliveryAttempts = email.deliveryAttempts + 1 email sendEmailSync() } case unexpectedMessage: Any => throw new Exception("can't handle %s" format(unexpectedMessage)) } override def preRestart(reason: Throwable, message: Option[Any]) { context.system.scheduler.scheduleOnce(emailMessage.get.retryOn, self, emailMessage.get) } }
  7. MIXINS What can fish do? trait Swimmer { def swim

    = println("I'm swimming")} class Fish extends Swimmer ... trait Walker { def walk = println("I'm walking")} val mudSkipper = new Fish() with Walker mudSkipper.walk()
  8. IDIOMATIC DSL capable and idiomatic syntax http://stackoverflow.com/questions/3186783/interesting-dsls-implemented-in-scala /** Poll every

    second and stream messages **/ Iterator.continually( Option(queue .poll(1, TimeUnit.SECONDS))) .takeWhile(_ => running) foreach { msg => write(msg) } /** TDD and BDD ? **/ test("pop is invoked on an empty stack") { val emptyStack = new Stack[String] evaluating { emptyStack.pop() } should produce [NoSuchElementException] emptyStack should be ('empty) } /** DB manipulation ? **/ def songCountByArtistId: Query[GroupWithMeasures[Long,Long]] = from(artists, songs)((a,s) => where(a.id === s.artistId) groupBy(a.id) compute(count) ) /** Json manipulation ? **/ ("person" -> ("name" -> "Joe") ~ ("age" -> 35) ~ ("spouse" -> ("person" -> ("name" -> "Marilyn") ~ ("age" -> 33) ) ) ) /** Xml manipulation ? **/ val page = <html> <head> <title>Hello XHTML world</title> </head> <body> <h1>Hello world</h1> </body> </html>;
  9. 1. HOF Higher Order Functions A function that takes a

    function as argument or returns another function e.g. map & filter
  10. map sadness to happiness - JAVA public List<String> mapSadnessToHappiness (List<String>

    sadness) { List<String> happiness = new ArrayList<String>(sadness.size()); for (int i = 0; i < sadness.size(); i++) { String sadFace = sadness.get(i); String happyFace = sadFace.replace('(', ')'); happiness.add(happyFace); } return happiness; } List<String> sadness = Arrays.asList(":(", ":(", ":("); List<String> happiness = mapSadnessToHappiness(sadness);
  11. Idiomatic Transformations Count char occurrences on a String - JAVA

    public static int countCharOccurrences(String haystack, char needle) { int count = 0; for (int i = 0; i < haystack.length(); i++) { if (haystack.charAt(i) == needle) { count++; } } return count; } public static Map<Character, Integer> toCharOccurrenceMap(String haystack) { Map<Character, Integer> map = new HashMap<Character, Integer>(); if (haystack != null) { for (int i = 0; i < haystack.length(); i++) { char character = haystack.charAt(i); int count = countCharOccurrences(haystack, character); map.put(character, count); } } return map; } toCharOccurrenceMap("betabeers");
  12. Key differentiator Higher Order Functions help with most Collection problems

    that you usually solve by looping over and manually creating intermediate containers. Transformed results stay immutable and thread safe. No need to reinvent the wheel. Code becomes readable and idiomatic "betabeers" groupBy identity mapValues (_.size)
  13. Other Powerful HOF’s examples Sum (1 to 1000).reduceLeft( _ +

    _ ) (1 to 1000).sum Partition filter val (passed, failed) = List(49, 58, 88, 90) partition ( _ > 60 ) min List(14, 35, -7, 46, 98).min max List(14, 35, -7, 46, 98).max Imperative iteration (1 to 10) foreach (println) Parallel Collections (1 to 10).par foreach(_ => println(Thread.currentThread.getName))
  14. Become a Scala Master For comprehensions Case Classes Futures Options

    Traits Either Pattern Matching Monads Actors DSL’s ...