Introduction to Scala

30
Introduction to Scala and HOF’s

Transcript of Introduction to Scala

Page 1: Introduction to Scala

Introduction to Scala and HOF’s

Page 2: Introduction to Scala

Who am [email protected], Java, Objective-C

Page 3: Introduction to Scala

WHO USES SCALA?/47 DEGREES AND...

HSBC KLOUT

LINKEDIN

LIVING SOCIAL

QUORA

REMEMBER THE M

ILK

SEESMIC STACKMOB

TWITT

ER

TUMBLR

VMWARE YAMMER

NOVELL ...

AOL BOX

E-HARMONY

http://www.quora.com/Startups/What-startups-or-tech-companies-are-using-Scala

Page 4: Introduction to Scala

SCALA ECOSYSTEM/JUST A FEW...

Page 5: Introduction to Scala

LEARN SCALA/BOOKS

Page 6: Introduction to Scala

LEARN SCALA/FREE ONLINE COURSES

Page 7: Introduction to Scala

WORLD DOMINATION IS UNDERWAY/GET ON THE WAGON BEFORE ITS TOO LATE

Page 8: Introduction to Scala

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 valueval 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

Page 9: Introduction to Scala

WHY LEARN SCALA?/A MODERN LANGUAGE FOR MASSIVE CONCURRENT APPLICATIONS IN THE CLOUD

Page 10: Introduction to Scala

SHOW ME THE CODE!!!

Page 11: Introduction to Scala

IMMUTABILITY In Java we tend to use Mutable structures that need synchronizationJAVA

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 valuesSCALA

val ints = for (num <- numbersAsStrings; if num.toInt % 2 == 0) yield num.toInt

No need to synchronize in structures which state is never modified

Page 12: Introduction to Scala

FUNCTIONAL In Scala everything returns a value

scala> val myInt = 1myInt: Int = 1

scala> def myFunction = "I don't need a return"myFunction: String

scala> val result = for (n <- 0 to 10) yield nresult: 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) }

Page 13: Introduction to Scala

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))}

Page 14: Introduction to Scala

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) } }

Page 15: Introduction to Scala

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 WalkermudSkipper.walk()

Page 16: Introduction to Scala

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>;

Page 17: Introduction to Scala

1. HOF Higher Order FunctionsA function that takes a function as argument

or returns another functione.g. map & filter

Page 18: Introduction to Scala

map transforms data

Page 19: Introduction to Scala

map sadness to happiness

:( :( :( => :) :) :)

Page 20: Introduction to Scala

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);

Page 21: Introduction to Scala

map sadness to happiness - Scala

List(":(", ":(", ":(").map(face => face.replace('(', ')'))

Page 22: Introduction to Scala

map sadness to happiness - Scala

List(":(", ":(", ":(").map(_.replace('(', ')'))

Page 23: Introduction to Scala

filter remove the unwanted

Page 24: Introduction to Scala

filter sadness keeping happiness

:) :) :( => :) :)

Page 25: Introduction to Scala

filter sadness keeping happiness

List(":)", ":)", ":(").filter(_.contains(":)"))

Page 26: Introduction to Scala

Idiomatic TransformationsCount 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");

Page 27: Introduction to Scala

Idiomatic TransformationsCount char occurrences on a String

"betabeers" groupBy identity mapValues (_.size)

Page 28: Introduction to Scala

Key differentiatorHigher 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)

Page 29: Introduction to Scala

Other Powerful HOF’s examples

Sum(1 to 1000).reduceLeft( _ + _ )

(1 to 1000).sum

Partition filterval (passed, failed) = List(49, 58, 88, 90) partition ( _ > 60 )

minList(14, 35, -7, 46, 98).min

maxList(14, 35, -7, 46, 98).max

Imperative iteration(1 to 10) foreach (println)

Parallel Collections(1 to 10).par foreach(_ => println(Thread.currentThread.getName))

Page 30: Introduction to Scala

Become a Scala Master

For comprehensionsCase Classes

FuturesOptionsTraitsEither

Pattern MatchingMonadsActorsDSL’s

...