Scala presentation by Aleksandar Prokopec

5,713 views

Published on

Published in: Technology
0 Comments
18 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,713
On SlideShare
0
From Embeds
0
Number of Embeds
589
Actions
Shares
0
Downloads
180
Comments
0
Likes
18
Embeds 0
No embeds

No notes for slide

Scala presentation by Aleksandar Prokopec

  1. 1. Introduction to Scala Aleksandar Prokopec EPFL
  2. 3. Pragmatic Since 2003 runs on the JVM Seamless Java interoperability Statically typed Production ready Martin Odersky Hybrid
  3. 4. Statically typed
  4. 5. runs on the JVM
  5. 6. Scala programs are fast.
  6. 7. OOP + FP
  7. 8. “ I can honestly say if someone had shown me the  Programming Scala  book by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I'd probably have never created Groovy.“ James Strachan, creator of Groovy
  8. 9. “ If I were to pick a language to use today other than Java, it would be Scala .” James Gosling
  9. 10. Pragmatic
  10. 11. Scala is lightweight.
  11. 12. println( “Hello world!” )
  12. 13. scala> println( “Hello world!” ) Hello world! REPL evaluating expressions on the fly
  13. 14. object MyApp extends App { println( “Hello world!” ) } Compiled version
  14. 15. object MyApp extends App { println( “Hello world!” ) } Singleton object s no more static methods
  15. 16. object MyApp { def main(args: Array[String]) { println( “Hello world!” ) } } Declaring methods
  16. 17. object MyApp { def main(args: Array[String]) { var user: String = args(0) println( “Hello, ” +user+ “!” ) } } Declaring var iables
  17. 18. object MyApp { def main(args: Array[String]) { val user: String = args(0) println( “Hello, ” +user+ “!” ) } } Declaring val ues prevents accidental changes
  18. 19. object MyApp { def main(args: Array[String]) { val user = args(0) println( “Hello, ” +user+ “!” ) } } Local type inference less… “typing”
  19. 20. class StringArrayFactory { def create : Array[String] = { val array: Array[String] = Array [String] ( “1” , “2” , “3” ) array } } Local type inference less… “typing”
  20. 21. class StringArrayFactory { def create = { val array = Array( “1” , “2” , “3” ) array } } Local type inference less… “typing”
  21. 22. // Scala class Person( var name: String, var age: Int ) Declaring class es … concisely // Java public class Person { private String name; private int age; public Person(String name, int age) { this .name = name; this .age = age; } public String getName() { return name; } public int getAge() { return age; } public void setName(String name) { this .name = name; } public void setAge( int age) { this .age = age; } }
  22. 23. Scala is object-oriented.
  23. 24. object Foo { val b = new ArrayBuffer[Any] } Object-oriented everything’s an object
  24. 25. Object-oriented everything’s an object Any AnyRef AnyVal String Boolean Char Int
  25. 26. object Foo { val b = new ArrayBuffer[Any] b += 1 b += 1.toString b += Foo println(b) } Object-oriented everything’s an object
  26. 27. 1 + 2 1.+(2) Array(1, 2, 3) ++ Array(4, 5, 6) Array(1, 2, 3).++(Array(4, 5, 6)) 1 :: List(2, 3) List(2, 3).::(1) Operator overloading operators are methods
  27. 28. trait Iterator[T] { def next(): T def hasNext: Boolean } Declaring trait s traits are like interfaces
  28. 29. trait Iterator[T] { def next(): T def hasNext: Boolean def printAll() = while (hasNext) println(next()) } Declaring trait s traits are rich
  29. 30. trait Animal Multiple inheritance traits are composable
  30. 31. trait Animal trait Mammal extends Animal { def think() = println( “hm...” ) } Multiple inheritance traits are composable
  31. 32. trait Animal trait Mammal extends Animal { def think() = println( “hm...” ) } trait Bird extends Animal { def layEgg() = System.createEgg() } Multiple inheritance traits are composable
  32. 34. trait Animal trait Mammal extends Animal { def think() = println( “hm...” ) } trait Bird extends Animal { def layEgg() = System.createEgg() } class Platypus extends Bird with Mammal Mixin composition traits are composable
  33. 35. trait Animal trait Reptile extends Animal { def layInTheSun : Unit = {} } class Dog(name: String) extends Mammal new Dog( “Nera” ) with Reptile Dynamic mixin composition … or composition “on the fly”
  34. 36. Cake pattern
  35. 37. trait Logging { def log(msg: String) } trait AnsweringMachine { self: Logging with DAO with Protocol => log( “Initializing.” ) ... } Self -types to express requirements
  36. 38. trait ConsoleLogging { def log(msg: String) = println(msg) } class LocalAnsweringMachine extends AnsweringMachine with ConsoleLogging with H2DAO with JabberProtocol Cake pattern layers above layers
  37. 39. Scala is functional.
  38. 40. (x: Int) => x + 1 First class functions
  39. 41. val doub : Int => Int = (x: Int) => x * 2 doub(1)  2 First class functions functions are objects too
  40. 42. val doub = (x: Int) => x * 2 List(1, 2, 3).map(doub)  List(2, 4, 6) First class functions as higher order parameters
  41. 43. List [Int] (1, 2, 3).map((x: Int) => x * 2) // more type inference List(1, 2, 3).map(x => x * 2) // or even shorter List(1, 2, 3).map(_ * 2) Functions with sugar make code sweeter
  42. 44. var step = 1 val inc = x => x + step inc(5)  6 step = 2 inc(5)  7 Closures functions that “capture” their environment
  43. 45. // Java button.addMouseListener( new MouseAdapter() { public void mouseEntered(MouseEvent e) { System.out.println(e); } } // Scala listenTo(button) reactions += { case e => println(e) } First class functions because you write them in Java all the time
  44. 46. Pattern matching
  45. 47. Pattern matching … is concise // Scala reactions += { case m: MouseEntered => println( “I see it!” ) case m: MouseExited => println( “Lost it.” ) case m: MouseClicked => println( “Poked!” ) } // Java button.addMouseListener( new MouseAdapter() { public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseEntered(MouseEvent e) { System.out.println( “I see it!” ); } public void mouseExited(MouseEvent e) { System.out.println( “Lost it.” ); } public void mouseClicked(MouseEvent e) { System.out.println( “Poked!” ); } } // ...alternative - isinstanceof
  46. 48. trait Tree case class Node(l: Tree, r: Tree) extends Tree case object Leaf extends Tree Pattern matching … is precise
  47. 49. def b(t: Tree): Int = t match { case Node(Leaf, Node(_, _)) | Node(Node(_, _), Leaf) => -1 case Node(l, r) => val (ld, rd) = (b(l), b(r)) if (ld == rd) ld + 1 else -1 case Leaf => 0 case _ => error( “Unknown tree!” ) } Pattern matching … is precise
  48. 50. sealed trait Tree ... def b(t: Tree): Int = t match { case Node(Leaf, Node(_, _)) | Node(Node(_, _), Leaf) => -1 case Node(l, r) => val (ld, rd) = (b(l), b(r)) if (ld == rd) ld + 1 else -1 case Leaf => 0 } Pattern matching … is exhaustive
  49. 51. def matchingMeSoftly(a: Any): Any = a match { case 11 => “eleven” case s: String => “’%s’” .format(s) case <tag> {t} </tag> => t case Array(1, 2, 3) => “1, 2, 3” case head :: tail => tail case _ => null } Pattern matching … is extensible
  50. 52. Lazyness
  51. 53. lazy values don’t compute if there’s no demand class User(id: Int) { lazy val followernum = from(followers)(f => where(id === f.fid) compute(countDistinct(f.fid)) ) }
  52. 54. Call by name evaluate only when you have to def withErrorOut(body: => Unit) = { val old = Console.out Console.setOut(Console.err) try body finally Console.setOut(old) } ... withErrorOut { if (n < 0) println( “n too small” ) }
  53. 55. Stream s lazy lists e = ∑ 1/n! = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + …
  54. 56. Stream s lazy lists e = ∑ 1/n! = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + … 0! ?
  55. 57. Stream s lazy lists e = ∑ 1/n! = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + … 0! 1! 2! 3! ? 0! ?
  56. 58. Stream s lazy lists e = ∑ 1/n! = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + … 0! 1! 2! 3! ? 0! ? 0! 1/1! 1/2! 1/3! ?
  57. 59. Stream s lazy lists def fact(n: Int, p: Int): Stream[Int] = p #:: fact(n + 1, p * (n + 1)) val factorials = fact(0, 1) val e = factorials.map(1./_).take(10).sum
  58. 60. Scala is expressive.
  59. 61. for comprehensions traverse anything for (x <- List(1, 2, 3)) println(x) List(1, 2, 3).foreach(x => println(x)) for (x <- 0 until 10) println(x) (0 until 10).foreach(x => println(x)) Range(0, 10, 1).foreach(x => println(x))
  60. 62. for comprehensions map anything for (x <- List(1, 2, 3)) yield x * 2 List(1, 2, 3).map(x => x * 2) for (x <- List(1, 2); y <- List(1, 2)) yield x * y List(1, 2).flatMap(x => List(1, 2).map(y => x * y) )  List(1, 2, 2, 4)
  61. 63. for comprehensions like SQL queries for { p <- people if p.age > 25 s <- schools if p.degree == s.degree } yield (p, s) // pairs of people older than 25 and // schools they possibly attended
  62. 64. Collections easy to create val phonebook = Map( “ Jean” -> “123456” , “ Damien” -> “666666” ) val meetings = ArrayBuffer( “ Dante” , “Damien” , “Sophie” ) println(phonebook(meetings(1)))
  63. 65. Collections high-level combinators // Java boolean isOk = true for ( int i = 0; i < name.length(); i++) { if (isLetterOrDigit(name.charAt(i)) { isOk = false ; break ; } }
  64. 66. Collections high-level combinators // Scala name.forall(_.isLetterOrDigit)
  65. 67. Collections high-level combinators // count the total number of different // surnames shared by at least 2 adults people
  66. 68. Collections high-level combinators // count the total number of different // surnames shared by at least 2 adults people.filter(_.age >= 18)
  67. 69. Collections high-level combinators // count the total number of different // surnames shared by at least 2 adults people.filter(_.age >= 18) .groupBy(_.surname) : Map[String, List[Person]]
  68. 70. Collections high-level combinators // count the total number of different // surnames shared by at least 2 adults people.filter(_.age >= 18) .groupBy(_.surname) : Map[String, List[Person]] .count { case (s, l) => l.size >= 2 }
  69. 71. List s an immutable sequence val countdown = List(3, 2, 1) 3 2 1 countdown
  70. 72. List s an immutable sequence val countdown = List(3, 2, 1) val longer = 4 :: countdown 3 2 1 4 countdown longer
  71. 73. List s an immutable sequence val countdown = List(3, 2, 1) val longer = 4 :: countdown val fast = 10 :: countdown 3 2 1 4 10 countdown longer fast
  72. 74. List s an immutable sequence val countdown = List(3, 2, 1) val longer = 4 :: countdown val fast = 10 :: countdown val withzero = countdown ::: List(0) 3 2 1 4 10 3 2 1 0 countdown longer fast withzero
  73. 75. Buffer s mutable sequences val b = ArrayBuffer(1, 2, 3) b += 4 b += 5 b += 6  ArrayBuffer(1, 2, 3, 4, 5, 6)
  74. 76. Map s mutable or immutable, sorted or unsorted import collection._ val m = mutable.Map( “Heidfeld” -> 1, “ Schumacher” -> 2) m += “Hakkinen” -> 3 val im = immutable.Map( “Schumacher” -> 1)
  75. 77. Hash tries persistence through efficient structural sharing val im0: Map[Int, Int] = ... im0
  76. 78. Hash tries persistence through efficient structural sharing val im0: Map[Int, Int] = ... val im1 = im0 + (1 -> 1) im0 im1
  77. 79. Hash tries persistence through efficient structural sharing val im0: Map[Int, Int] = ... val im1 = im0 + (1 -> 1) val im2 = im1 + (2 -> 2) im0 im1 im2
  78. 80. Hash tries persistence through efficient structural sharing val im0: Map[Int, Int] = ... val im1 = im0 + (1 -> 1) val im2 = im1 + (2 -> 2) val im3 = im2 + (3 -> 6) im0 im1 im2 im3
  79. 81. Hash tries persistence through efficient structural sharing im0 im1 im2 im3 2x-3x slower lookup 2x faster iteration
  80. 82. Parallel collections parallelize bulk operations on collections def cntEqlen(m: Map[String, String]) = { m.par.count { case (n, s) => n.length == s.length } } // be careful with side-effects
  81. 83. Scala is extensible.
  82. 84. One ring to rule them all.
  83. 85. actor s road to safer concurrency val a = actor { react { case i: Int => println(i) } } ... a ! 5
  84. 86. Custom control flow it’s all about control def myWhile(c: => Boolean)(b: => Unit) { if (c) { b myWhile(c)(b) } }
  85. 87. Custom control flow it’s all about control @tailrec def myWhile(c: => Boolean)(b: => Unit) { if (c) { b myWhile(c)(b) } }
  86. 88. Custom control flow it’s all about control @tailrec def myWhile(c: => Boolean)(b: => Unit) { if (c) { b myWhile(c)(b) } } var i = 0 myWhile (i < 5) { i += 1 }
  87. 89. ARM automatic resource management withFile ( “~/.bashrc” ) { f => for (l <- f.lines) { if ( “#” .r.findFirstIn(l) != None) println(l) } }
  88. 90. ScalaTest behavioral testing framework “ A list” should { “ be a double reverse of itself” in { val ls = List(1, 2, 3, 4, 5, 6) ls.reverse.reverse should equal (ls) } }
  89. 91. BaySick Basic DSL in Scala 10 PRINT “Baysick Lunar Lander v0.9” 20 LET ('dist := 100) 30 LET ('v := 1) 40 LET ('fuel := 1000) 50 LET ('mass := 1000) ...
  90. 92. implicit conversions augmenting types with new operations ‘ a’ .toUpperCase
  91. 93. implicit conversions augmenting types with new operations implicit def charOps(c: Char) = new { def toUpperCase = if (c >= ‘a’ && c <= ‘z’) (c – 32).toChar else c } ... ‘ a’ .toUpperCase
  92. 94. Pimp my library
  93. 95. implicit conversions pimping your libraries since 2006 import scalaj.collection._ val list = new java.util.ArrayList[Int] list.add(1) list.add(2) list.add(3) ... for (x <- list) yield x * 2
  94. 96. implicit conversions pimping your libraries since 2006 import scalaj.collection._ val list = new java.util.ArrayList[Int] list.add(1) list.add(2) list.add(3) ... for (x <- list) yield x * 2 // list.map(x => x * 2)
  95. 97. implicit conversions pimping your libraries since 2006 import scalaj.collection._ val list = new java.util.ArrayList[Int] list.add(1) list.add(2) list.add(3) ... for (x <- list) yield x * 2 // jlist2slist(list).map(x => x * 2)
  96. 98. implicit arguments restricting operations on types val is = SortedSet(1, 2, 3) case class Man(id: Int) ... implicit object MenOrd extends Ordering[Man] { def compare(x: Man, y: Man) = x.id – y.id } val ms = SortedSet(Person(1), Person(2))
  97. 99. STM software transactional memory val account1 = cell[Int] val account2 = cell[Int] atomic { implicit txn => if (account2() >= 50) { account1 += 50 account2 -= 50 } }
  98. 100. Scala has support.
  99. 101. Building Ant SBT Maven
  100. 102. SBT simple build tool > compile ... > ~compile ... > test ... > package
  101. 103. SBT project definition written in Scala val scalatest = “ org.scala-tools.testing” % “ scalatest” % “0.9.5” ... > reload [INFO] Building project ... [INFO] using sbt.Default ... > update
  102. 104. Tools: IDEs Eclipse Netbeans IntelliJ IDEA Emacs ENSIME JEdit
  103. 105. Web frameworks
  104. 106. Used by...
  105. 107. Thank you!

×