Scala ntnu

628 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
628
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • Denne siden skal vel bort?
  • Bruke logging eksempelet
  • Logging?
  • Scala ntnu

    1. 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. 2. Agenda ● Background and motivation ● Intro to Scala ● Basic syntax ● Pattern matching ● Functions ● Classes and traits ● <break /> ● Practical Scala
    3. 3. About us ● Alf Kristian Støyle 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. 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. 5. List<Person> persons = ... List<Person> adults = new LinkedList<Person>(); List<Person> kids = new LinkedList<Person>(); 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. 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. 7. Scala ● Object oriented and functional ● Statically typed ● Java compatible ● Compiles to Java bytecode ● Existing libraries/frameworks ● Better Java
    8. 8. http://4.bp.blogspot.com/_RshsKGzNxWA/TB9QhCXK0fI/AAAAAAAAAEc/MFwujJaIRmw/s1600/BlueRedPill.jpg
    9. 9. Variables var i: Int = 42
    10. 10. Variables var i = 42 i = 3 i = "Hello world!" // compile error
    11. 11. Values val i = 42 i = 3 // compile error
    12. 12. Methods def sum(a: Int, b: Int): Int = { return a + b }
    13. 13. Methods def sum(a: Int, b: Int): Int = { a + b }
    14. 14. Methods def sum(a: Int, b: Int) = { a + b }
    15. 15. Methods def sum(a: Int, b: Int) = a + b
    16. 16. Methods "apple".charAt(0) "apple" charAt 0 1.0.+(2.0) 1.0 + 2.0
    17. 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. 18. myObject match { case 1 => println("First") case 2 => println("Second") case _ => println("Unknown") } Pattern matching
    19. 19. myObject match { case i: Int => println("Found number " + i) case s: String => println("Found text " + s) case _ => println("Unknown") } Pattern matching
    20. 20. val email = """(.+)@(.+)""".r "scala@java.no" match { case email(name, domain) => println("User " + name + " at " + domain) case x => println(x + " is not an email") } Pattern matching
    21. 21. Functions
    22. 22. Functions Predicate<Integer> even = new Predicate<Integer>() { @Override public boolean apply(Integer i) { return i % 2 == 0; } }; List<Integer> numbers = … // 1, 2, 3, 4 Iterable<Integer> evenNums = Iterables.filter(numbers, even); => [2, 4] Google collections:
    23. 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. 24. Functions val numbers = List(1, 2, 3, 4) val evenNums = numbers.filter((i: Int) => i % 2 == 0) => List(2, 4) Scala collections:
    25. 25. Functions val numbers = List(1, 2, 3, 4) val evenNums = numbers.filter(i => i % 2 == 0) => List(2, 4) Scala collections:
    26. 26. Functions val numbers = List(1, 2, 3, 4) val evenNums = numbers.filter(_ % 2 == 0) => List(2, 4) Scala collections:
    27. 27. Functions Predicate<Integer> even = new Predicate<Integer>() { @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. 28. “Functional programming” ● First class functions ● Pattern matching ● …
    29. 29. Functional programming ● Mathematical functions have no side effects ● f(x) = 2x + 3
    30. 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. 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. 32. Strive to be pure ● Concurrency ● Easier to avoid errors ● Easier to test
    33. 33. Control structures return values val numbers = for (i <- 1 to 10) yield i val res1 = if (cond) x else y val res2 = try { x } catch { … y } finally { … }
    34. 34. Classes and constructors class Person(val name: String, val age: Int)
    35. 35. Classes and constructors class Person(val name: String, val age: Int) { def this(name: String) = this(name, 42) override def toString = "My age is " + age }
    36. 36. Traits (= Interface + Mixin) ● “Multiple inheritance done right” ● Implement methods ● Initialize fields
    37. 37. scala.Ordered trait trait Ordered[A] { def compare(that: A): Int def < (that: A) = this.compare(that) < 0 def > (that: A) = this.compare(that) > 0 def <= (that: A) = this.compare(that) <= 0 def >= (that: A) = this.compare(that) >= 0 }
    38. 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.<(person2) // true person1 <= person2 // true person1 >= person2 // false
    39. 39. Just scratching the surface... ● Tuples ● Singleton objects ● Closures ● For-comprehensions ● Implicit conversions ● Actors ● Native XML data types ● Parsers
    40. 40. Q & A
    41. 41. val xml = <break time="30" />
    42. 42. Practical Scala ● The downside ● Tools ● ScalaTest ● Java interoperability ● Learning curve ● Your choice ● Implicit conversions ● Higher order functions
    43. 43. IDE support ● Netbeans - very good, but inferior in other areas ● IntelliJ IDEA - very good, but slow compilation ● Eclipse - getting better, very fast when working
    44. 44. Backward compatibility ● Binary compatibility broken several times ● Think twice before using a library ● 2.7.3 – 2.7.4 ● 2.8.0 <-> 2.8.1.RC4
    45. 45. Tools demo ● REPL - Read eval print loop ● Maven ● SBT - Simple Build Tool ● IntelliJ IDEA
    46. 46. ScalaTest demo ● DSL for testing ● Powerful assertions ● Different test styles ● JUnit ● Functional tests ● BDD test
    47. 47. The feel of Scala http://parleys.com/#id=10&st=5&sl=1
    48. 48. Java interoperability demo ● Scala using Java ● Java using Scala ● Mixed projects?
    49. 49. Learning curve ● Syntax small smack in the face ● Easy to write Java-ish Scala ● The language scales with your understanding ● Gradually migrate to more functional style
    50. 50. What would you like to hear? ● Implicit conversion ● Why does "gnirtS.gnal.avaj".reverse work? ● Higher order functions ● How does the using/resource handling example work?
    51. 51. Higher order functions
    52. 52. Higher order functions ● Functions which take functions as parameters and/or return functions
    53. 53. Higher order functions First class functions: val even: (Int => 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. 54. Higher order functions def test(numbers: List[Int], f: Int => Boolean): List[Boolean] = numbers.map(tall => f(tall))
    55. 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. 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. 57. call-by-value vs. call-by-name Example: Logging def thisTakesTime = { println(“Slow computation”) “result” }
    58. 58. call-by-value def debug(s: String) { println(“debug”) if (logLevel <= DEBUG) println(s) } logger.debug(thisTakesTime()) // Slow computation // debug // result
    59. 59. call-by-name def debug(s: => String) { println(“debug”) if (logLevel <= DEBUG) println(s) } logger.debug(thisTakesTime()) // debug // Slow computation // result
    60. 60. 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 } } }
    61. 61. def using[T <: { def close() }, A] (closeable: T) (f: 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. 62. Implicit conversions
    63. 63. String s = "!em esreveR"; System.out.println(s.reverse()); Magic? val s: java.lang.String = "!em esreveR" println(s.reverse) => Reverse me!
    64. 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. 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. 66. implicit implicit def augmentString(x: String) = new StringOps(x)
    67. 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. 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. 69. Map and ArrowAssoc val myMap: Map[Int, String] = Map(1 -> "one", 2 -> "two")
    70. 70. Map and ArrowAssoc val myMap: Map[Int, String] = Map(1 -> "one", 2 -> "two") Map.apply((1, "one"), (2, "two"))
    71. 71. Map and ArrowAssoc val myMap: Map[Int, String] = Map(1 -> "one", 2 -> "two") Map((1, "one"), (2, "two"))
    72. 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. 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. 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. 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. 76. Q & A
    77. 77. Resources ● scala@java.no (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 ● fvr@knowit.no, aks@knowit.no

    ×