scala ntnu

Download Scala ntnu

If you can't read please download the document

Upload: alf-kristian-stoyle

Post on 30-Jun-2015

389 views

Category:

Documents


2 download

TRANSCRIPT

  • 1. If I were to pick a language to use on the JVM today other than Java, it would be Scala. James Gosling, creator of Java http://www.adam-bien.com/roller/abien/entry/java_net_javaone_which_programming Scala, it must be stated, is the current heir apparent to the Java throne. No other language on the JVM seems as capable of being a "replacement for Java" as Scala, and the momentum behind Scala is now unquestionable. Charlies Nutter, JRuby lead http://blog.headius.com/2009/04/future-part-one.html My tip though for the long term replacement of javac is Scala. I'm very impressed with it! I can honestly say if someone had shown me the Programming in Scala book [] back in 2003 I'd probably have never created Groovy. James Strachan, creator of Groovy http://macstrac.blogspot.com/2009/04/scala-as-long-term-replacement-for.html

2. Agenda Background and motivation Intro to Scala Basic syntax Pattern matching Functions Classes and traits Practical Scala 3. About us Alf Kristian Style and Fredrik Vraalsen Java developers with 6 and 9 years experience Scala enthusiasts since 2008 Developed SubmitIT for JavaZone Alf worked on Scala projects for Kommuneforlaget Held 4 Scala training courses for 60+ participants 4. public class Person { private int age; private String name; public Person(int age, String name) { this.age = age; this.name = name; } public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } } class Person(var age: Int, var name: String) 5. List persons = ... List adults = new LinkedList(); List kids = new LinkedList(); for (Person person : persons) { if (person.getAge() < 18) { kids.add(person); } else { adults.add(person); } } val persons: List[Person] = ... val (kids, adults) = persons.partition(_.age < 18) 6. using(new BufferedReader(new FileReader("f.txt"))) { reader => println(reader.readLine()) } BufferedReader reader = null; try { reader = new BufferedReader(new FileReader("f.txt")); System.out.println(reader.readLine()); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { // Exception on close, ignore } } } 7. Scala Object oriented and functional Statically typed Java compatible Compiles to Java bytecode Existing libraries/frameworks Better Java 8. http://4.bp.blogspot.com/_RshsKGzNxWA/TB9QhCXK0fI/AAAAAAAAAEc/MFwujJaIRmw/s1600/BlueRedPill.jpg 9. Variables var i: Int = 42 10. Variables var i = 42 i = 3 i = "Hello world!" // compile error 11. Values val i = 42 i = 3 // compile error 12. Methods def sum(a: Int, b: Int): Int = { return a + b } 13. Methods def sum(a: Int, b: Int): Int = { a + b } 14. Methods def sum(a: Int, b: Int) = { a + b } 15. Methods def sum(a: Int, b: Int) = a + b 16. Methods "apple".charAt(0) "apple" charAt 0 1.0.+(2.0) 1.0 + 2.0 17. Collections val list = List("apple", "orange", "banana") val map = Map(1 -> "one", 2 -> "two") val array = Array(1, 2, 3, 4, 5) list(1) // orange map(2) // two array(3) // 4 18. myObject match { case 1 => println("First") case 2 => println("Second") case _ => println("Unknown") } Pattern matching 19. myObject match { case i: Int => println("Found number " + i) case s: String => println("Found text " + s) case _ => println("Unknown") } Pattern matching 20. val email = """(.+)@(.+)""".r "[email protected]" match { case email(name, domain) => println("User " + name + " at " + domain) case x => println(x + " is not an email") } Pattern matching 21. Functions 22. Functions Predicate even = new Predicate() { @Override public boolean apply(Integer i) { return i % 2 == 0; } }; List numbers = // 1, 2, 3, 4 Iterable evenNums = Iterables.filter(numbers, even); => [2, 4] Google collections: 23. Functions val even = (i: Int) => i % 2 == 0 val numbers = List(1, 2, 3, 4) val evenNums = numbers.filter(even) => List(2, 4) Scala collections: 24. Functions val numbers = List(1, 2, 3, 4) val evenNums = numbers.filter((i: Int) => i % 2 == 0) => List(2, 4) Scala collections: 25. Functions val numbers = List(1, 2, 3, 4) val evenNums = numbers.filter(i => i % 2 == 0) => List(2, 4) Scala collections: 26. Functions val numbers = List(1, 2, 3, 4) val evenNums = numbers.filter(_ % 2 == 0) => List(2, 4) Scala collections: 27. Functions Predicate even = new Predicate() { @Override public boolean apply(Integer i) { return i % 2 == 0; } }; val numbers = List(1, 2, 3, 4) val evenNums = numbers.filter(_ % 2 == 0) => List(2, 4) Scala collections: 28. Functional programming First class functions Pattern matching 29. Functional programming Mathematical functions have no side effects f(x) = 2x + 3 30. In practice Only immutable objects (and object graphs) All field must be immutable No side-effects from method calls All methods must return something 31. Immutable datastrukturer for (Iterator i = persons.iterator(); i.hasNext();) { Person person = (Person) i.next(); if (person.getAge() < 18) { i.remove(); } } val adults = persons.filter(_.age >= 18) 32. Strive to be pure Concurrency Easier to avoid errors Easier to test 33. Control structures return values val numbers = for (i (that: A) = this.compare(that) > 0 def = 0 } 38. The Ordered trait class Person(val age: Int) extends Ordered[Person] { def compare(other: Person) = this.age - other.age } val person1 = new Person(21) val person2 = new Person(31) person1. Boolean) = (i: Int) => i % 2 == 0 Higher order function: def test(numbers: List[Int], f: Int => Boolean) = ... Use: test(List(1, 2, 3), (i: Int) => i % 2 == 0) test(List(1, 2, 3), _ % 2 == 0) 54. Higher order functions def test(numbers: List[Int], f: Int => Boolean): List[Boolean] = numbers.map(tall => f(tall)) 55. Higher order functions def test(numbers: List[Int], f: Int => Boolean): List[Boolean] = numbers.map(tall => f(tall)) Use: test(List(1, 2, 3), _ % 2 == 0) // List(false, true, false) 56. call-by-value vs. call-by-name by-value: expressions are evaluated before being passed to the function by-name: expressions evaluated inside function nice when computationally expensive possible to create nice APIs 57. call-by-value vs. call-by-name Example: Logging def thisTakesTime = { println(Slow computation) result } 58. call-by-value def debug(s: String) { println(debug) if (logLevel String) { println(debug) if (logLevel println(reader.readLine()) } BufferedReader reader = null; try { reader = new BufferedReader(new FileReader("f.txt")); System.out.println(reader.readLine()); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { // Exception on close, ignore } } } 61. def using[T A) = { try { f(closeable) } finally { if (closeable != null) { try { closeable.close() } catch { case e: Exception => // Ignore } } } } using(new BufferedReader(new FileReader("f.txt"))) { reader => println(reader.readLine()) } 62. Implicit conversions 63. String s = "!em esreveR"; System.out.println(s.reverse()); Magic? val s: java.lang.String = "!em esreveR" println(s.reverse) => Reverse me! 64. Magic? val s: java.lang.String = "!em esreveR" println(s.reverse) println(stringWrapper(s).reverse) => Reverse me! String s = "!em esreveR"; System.out.println(s.reverse()); 65. Magic? val s: java.lang.String = "!em esreveR" println(s.reverse) println(augmentString(s).reverse) println(new StringOps(s).reverse) => Reverse me! String s = "!em esreveR"; System.out.println(s.reverse()); 66. implicit implicit def augmentString(x: String) = new StringOps(x) 67. StringOps def toArray : Array[Char] def toBoolean : Boolean def toByte : Byte def toDouble : Double def toFloat : Float def toInt : Int def toLong : Long def toShort : Short def r : Regex def lines : Iterator[java.lang.String] def * (n : Int) : java.lang.String ... 68. scala.Predef A set of implicits byteWrapper(x: Byte) shortWrapper(x: Short) intWrapper(x: Int) charWrapper(c: Char) longWrapper(x: Long) floatWrapper(x: Float) doubleWrapper(x: Double) booleanWrapper(x: Boolean) stringWrapper(x: String) stringBuilderWrapper(x : StringBuilder) ... 69. Map and ArrowAssoc val myMap: Map[Int, String] = Map(1 -> "one", 2 -> "two") 70. Map and ArrowAssoc val myMap: Map[Int, String] = Map(1 -> "one", 2 -> "two") Map.apply((1, "one"), (2, "two")) 71. Map and ArrowAssoc val myMap: Map[Int, String] = Map(1 -> "one", 2 -> "two") Map((1, "one"), (2, "two")) 72. Map and ArrowAssoc val myMap: Map[Int, String] = Map(1 -> "one", 2 -> "two") Map((1, "one"), (2, "two")) val tuple: Tuple2[Int, String] = (1, "one") 73. Map and ArrowAssoc val myMap: Map[Int, String] = Map(1 -> "one", 2 -> "two") Map(any2ArrowAssoc(1) -> "one", any2ArrowAssoc(2) -> "two") Map((1, "one"), (2, "two")) 74. scala.Predef.ArrowAssoc implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x) class ArrowAssoc[A](x: A) { def -> [B](y: B): Tuple2[A, B] = (x, y) } val myMap = Map(1 -> "one", 2 -> "two") 75. Implicit rules! Marking Rule: Only definitions marked implicit are available. Scope Rule: An inserted implicit conversion must be in scope as a single identifier, or be associated with the source or target type of the conversion. Non-Ambiguity Rule: An implicit conversion is only inserted if there is no other possible conversion to insert. One-at-a-time Rule: Only one implicit is tried. Explicits-First Rule: Whenever code type checks as it is written, no implicits are attempted. 76. Q & A 77. Resources [email protected] (http://lister.java.no/mailman/listinfo/scala) http://scala.java.no http://www.slideshare.net/stoyle/scala-ntnu http://github.com/javaBin/scala-training-slides [email protected], [email protected]