Introduction to Scala
-
Upload
raulraja -
Category
Technology
-
view
703 -
download
1
Transcript of Introduction to Scala
Introduction to Scala and HOF’s
Who am [email protected], Java, Objective-C
WHO USES SCALA?/47 DEGREES AND...
HSBC KLOUT
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
SCALA ECOSYSTEM/JUST A FEW...
LEARN SCALA/BOOKS
LEARN SCALA/FREE ONLINE COURSES
WORLD DOMINATION IS UNDERWAY/GET ON THE WAGON BEFORE ITS TOO LATE
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
WHY LEARN SCALA?/A MODERN LANGUAGE FOR MASSIVE CONCURRENT APPLICATIONS IN THE CLOUD
SHOW ME THE CODE!!!
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
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) }
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))}
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) } }
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()
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>;
1. HOF Higher Order FunctionsA function that takes a function as argument
or returns another functione.g. map & filter
map transforms data
map sadness to happiness
:( :( :( => :) :) :)
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);
map sadness to happiness - Scala
List(":(", ":(", ":(").map(face => face.replace('(', ')'))
map sadness to happiness - Scala
List(":(", ":(", ":(").map(_.replace('(', ')'))
filter remove the unwanted
filter sadness keeping happiness
:) :) :( => :) :)
filter sadness keeping happiness
List(":)", ":)", ":(").filter(_.contains(":)"))
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");
Idiomatic TransformationsCount char occurrences on a String
"betabeers" groupBy identity mapValues (_.size)
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)
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))
Become a Scala Master
For comprehensionsCase Classes
FuturesOptionsTraitsEither
Pattern MatchingMonadsActorsDSL’s
...