Workshop Scala

Download Workshop Scala

Post on 28-Jan-2015




0 download

Embed Size (px)


I used these slides for a Scala workshop that I gave. They are based on these: Thanks to Alf Kristian Style and Fredrik Vraalsen for sharing!


<ul><li> 1. Scala workshop Created byFredrik Vraalsen ( andAlf Kristian Style ( AdaptedBert Van Vreckem (</li></ul><p> 2. If I were to pick a language to usetoday other than Java, it would beScala.James Gosling 3. Scala, it must be stated, is the current heirapparent to the Java throne. No other language on the JVM seems as capable of being a "replacement for Java" as Scala, and themomentum behind Scala is now unquestionable.Charlies Olivier Nutter - JRuby lead 4. Though my tip though for the long termreplacement of javac is Scala. Im very impressed with it! I can honestly say ifsomeone had shown me the Programming in Scala book by by Martin Odersky, Lex Spoon &amp; Bill Venners back in 2003 Idprobably have never created Groovy. James Strachen 5. public class Person {private int age;private String name;public Person(int age, String name) {this.age = age; = name;}public int getAge() {return this.age;}public void setAge(int age) {this.age = age;}public String getName() {return;}public void setName(String name) { = name;}}class Person(var age: Int, var name: String) 6. List persons = ...List adults = new LinkedList();List kids = new LinkedList();for (Person person : persons) {if (person.getAge() &lt; 18) {kids.add(person);} else {adults.add(person);}} val (kids, adults) = persons.partition(_.age &lt; 18) 7. String s = "!em esreveR";System.out.println(s.reverse()); val s = "!em esreveR" println(s.reverse) =&gt; Reverse me! 8. 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}}}using(new BufferedReader(new FileReader("f.txt"))) {reader =&gt; println(reader.readLine())} 9. I will never forget these words: "With great powercomes great responsibility." This is my gift, my curse. Who am I? Im Spider-man. 10. val myList = List(1, 2, 3)val res = (10 /: myList)(_+_)=&gt; ?? 11. Scala Object oriented and functional Statically typed Java compatible Complies to Java bytecode (and CLR) Existing libraries/frameworks Better Java 12. Todays schedule Basic syntax REPL, IDEs and setup First class functions Pattern matching OO and traits Functional programming Higher order functions 13. Scala basics 14. ; 15. Type definitionsScala Javas: String String si: Intint i / Integer i 16. VariablesScala: Java:val s = "Hello World"public final String s = "Hello World";var i = 1 public int i = 1;private var j = 3 private int j = 3; 17. Methods (3)Scala:Java:override def toString = ... @Overridepublic String toString(){...} 18. Classes and constructorsScala: Java:class Person(val name: public class Person {String) private final Stringname;public Person(Stringname) { = name;}public String getName() { return name;} } 19. Traits (= Interface + Mixin)Scala:Java:trait Shape { interface Shape { def area: Doublepublic double area();} }class Circle extends Object public class Circle extendswith ShapeObject implements Shape 20. No static in ScalaScala: Java:object PersonUtil {public class PersonUtil {val ageLimit = 18 public static final intAGE_LIMIT = 18;def countPersons(public static intpersons: List[Person]) = countPersons(...List persons)}{ ... } } 21. While-loopsScala: Java:while (true) { while (true) {......}} 22. ExceptionsScala:Java:throw new throw newException(...)Exception(...)try { try {} catch { } catch (IOException e) { case e: IOException ... =&gt; ... } finally {} finally { }} 23. Varargsdef foo(values: String*){ } public void foo(String... values){ }foo("bar", "baz") foo("bar", "baz");val arr = Array("bar", "baz") String[] arr =new String[]{"bar", "baz"}foo(arr: _*)foo(arr); 24. (Almost) everything is an expressionval res = if (foo) x else yval res = for (i ???SDate} 29. REPL, IDE and setup 30. REPL: Read-Eval-Print Loop Command line shell for on-the-fly execution ofScala statements$ cd ${SCALA_HOME}/bin$ scala Windows, e.g. C:Program FilesScala 2.8.0 Linux, e.g. /opt/scala or /usr/local/scala 31. IDE They are all !#$&amp;? compared to what you areused to with Java support Netbeans (very good) but bad in other areas... IntelliJ IDEA (pretty good) but slow compilation,bonus community edition is free (with Scala) Eclipse (not all that good) but very fast whenworking 32. Netbeans 6.9.x installation Download plugins In NetBeans "Tools" | "Plugins", click on "Downloaded" tab title, click on "Add Plugins..." button, choose the directory where the Scala plugins are unzipped, select all listed *.nbm files, following the instructions. Set ${SCALA_HOME} or %SCALA_HOME% environment variable Edit ${NETBEANS_HOME}/etc/netbeans.conf Add "-J-Dscala.home=/opt/scala" to netbeans_default_options More info: 33. Tasks (20 min) Run REPL Windows: %scala_home%/bin/scala Linux: scala or /opt/scala/bin/scala Execute a few statements Copy &amp; into DocumentenNetbeansProjects (Windows) Into /home/student/NetbeansProjects (Linux) 34. Tasks (20 min) Run unit test in IDE (JUnit 4) Open the ScalaTraining project in NetBeans Try to compile and test the project (should work) scalaexamples.intro.MyFirstTest Create a failing test Make it run Make the two classes scalaexamples/intro/HelloWorld.scalaprint Hello world. What is the difference? Remove comments from @Test for the methods inscalaexamples/intro/CreateStuffTest.scala. Make tests pass. 35. First class functions 36. First class functionsval even = Function[Int, Boolean] {def apply(i: Int) = i % 2 == 0}val even: (Int =&gt; Boolean) = (i: Int) =&gt; i % 2 == 0val even = (i: Int) =&gt; i % 2 == 0even.apply(42) // trueeven(13) // false 37. First class functionsval numbers = List(1, 2, 3, 4, 5)numbers.filter(even)// List(2, 4)numbers.filter((i: Int) =&gt; i &gt; 2) // List(3, 4, 5)numbers.filter(i =&gt; i &gt; 2)// List(3, 4, 5)numbers.filter(_ &gt; 2) // List(3, 4, 5) 38. Collectionsnumbers.filter(i =&gt; i &gt; 2) // List(3, 4, 5)numbers.find(i =&gt; i &gt; 2) // Some(3)numbers.exists(i =&gt; i &gt; 2) // truenumbers.forall(i =&gt; i &gt; 2) // =&gt; i * 2)// List(2, 4, 6, 8, 10)numbers.foldLeft(0) { (a, b) =&gt; a + b }// 15 39. Closuresval people = List(Person(Alf), Person(Fredrik))var name = Fredrikval nameFilter = (p: Person) =&gt; == namepeople.filter(nameFilter) // Person(Fredrik)name = Alfpeople.filter(nameFilter) // Person(Alf) 40. Tasks (30 min) Open the first-class-functions project Tests in packagescalaexamples.firstclassfunctions Add @Test to one and one method Follow instructions in the code Make the tests pass 41. Pattern matching 42. myObject match {case 1 =&gt; println("First was hit")case 2 =&gt; println("Second was Hit")case _ =&gt; println("Unknown")} 43. myObject match { case i: Int =&gt; println("Found an int") case s: String =&gt; println("Found a String") case _ =&gt; println("Unknown") } 44. myObject match { case i: Int =&gt; println("Found an int") case s: String =&gt; println("Found a String") case other =&gt; println("Unknown " + other) } 45. myObject match { case i: Int if i == 1 =&gt; println("Found an int") case s: String =&gt; println("Found a String") case other =&gt; println("Unknown " + other) } 46. val res = myObject match {case i: Int if i == 1 =&gt; "Found an int"case s: String =&gt; "Found a String"case other =&gt; "Unknown " + other} 47. val res = myObject match {case (first, second) =&gt; secondcase (first, second, third) =&gt; third} 48. val mathedElement = list match {case List(firstElement, lastElement) =&gt; lastElementcase List(firstElement, _ *) =&gt; firstElementcase _ =&gt; "failed"} 49. def length(list: List[_]): Int =list match {case Nil =&gt; 0case head :: tail =&gt; 1 + length(tail)} 50. public static Integer getSecondOr0(List list) {if (list != null &amp;&amp; list.size() &gt;= 2) {return list.get(1);} else {return 0;}}def second_or_0(list:List[Int]) = list match {case List(_, x, _*) =&gt; xcase _ =&gt; 0} 51. Case classes Class types that can be used in patternmatching Generated into your class: equals hashCode toString getters (and optionally setters) ++ 52. abstract class Person(name: String)case class Man(name: String) extends Person(name)case class Woman(name: String, children: List[Person])extends Person(name) 53. p match {case Man(name) =&gt; println("Man with name " + name)case Woman(name, children) =&gt; println("Woman with name "+ name + " and with " +children.size + " children")} 54. val regex = """(d+)(w+)""".rval myString = ...val res: String = myString match {case regex(digits, word) =&gt; digitscase _ =&gt; "None"} 55. val regex = """(d+)(w+)""".rval myString = ...val res: Option[String] = myString match {case regex(digit, word) =&gt; Some(digit)case _ =&gt; None} 56. The Option type, never again NullPointerException Option has two possible values Some(value) Noneval someOption: Option[String] = Some("value")val noOption: Option[String] = None 57. def getValue(s: Any): Option[String]getValue(object) match {case Some(value) =&gt; println(value)case None =&gt; println("Nothing")}val result = getValue(object).getOrElse("Nothing") 58. Tasks (30 min) Open the pattern-matching project Tests in packagescalaexamples.patternmatching Add @Test to one and one method Follow instructions in the code Make the tests pass 59. Object orientation andtraits 60. Annotations not marker interfaces @serializable class Person @SerialVersionUID(1) class Person @cloneable class Person @remote class Service 61. object object is a singleton classCall may look like static method calls in JavaCan inherit from other classes and traitsCan be passed as a referenceobject MyObject {def foo = "bar"}var baz = MyObject.fooval personObject = MyObjectbaz = 62. Companion object Can read the companion class private fields Has to be in the same source fileclass Person(private val age: Int)object Person {def getPersonAge(p: Person) = p.age}val personInstance = new Person(30)val age = Person.getPersonAge(personInstance) 63. Magical applyclass Person private(val age: Int)object Person {def apply(age: Int) = new Person(age)}var personInstance = Person.apply(30)personInstance = Person(30) 64. Not built in, clever use of applyval myList = List(1, 2, 3)val mySet = Set(1, 2, 3)val myMap = Map(1 -&gt; "one", 2 -&gt; "two") 65. Constructors Always one primary constructor Parameters are automatically instance variables Class body is the primary constructors content Auxiliary constructors MUST call or chain to primaryconstructorclass MyClass(myString: String, myInt: Int)val myOtherInt = 10println("In main body")} 66. Auxiliary constructorsclass MyClass(myString: String, myInt: Int) {def this(myString: String) = this(myString, 0)def this() = {this("foo")println("In default constructor")}} 67. Inheritanceclass MyClass(myString: String)class MySubClass(myString: String, myInt: Int)extends MyClass(myString) {println("MyString: " + myString +", MyInt: " + myInt + "")} 68. Inheritance Single class inheritance Multiple trait mixins 69. Syntaxclass Person extends AnyRef with with java.rmi.Remoteclass Person extends with java.rmi.Remote 70. Traits Multiple inheritance done right Implement methods Initialized fields Abstract methods Abstract fields Abstract types Does not have constructors Call to super strict semantics 71. scala.Ordered traittrait Ordered[A] {def compare(that: A): Intdef 0def = 0} 72. The Ordered traitclass Person(private 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 &lt; person2 // trueperson1 = person2 // false 73. Dynamic mixinsclass Person(age: Int) {override def toString = "my age is " + age}trait MyTrait {override def toString = "I am sure " +super.toString}val person = new Person(30) with MyTraitprintln(person)=&gt; I am sure my age is 30 74. is-a vs has-a Inheritance as usual Easier to implement has-a Inheritance vs composition 75. Tasks (30 min) Open oo-traits project Tests under scalaexamples companionobject inheritance traits Add @Test to one and one method Follow instructions in code Make tests pass 76. Functional programming 77. Functional programming First class functions Pattern matching Higher order functions 78. Functional programming Purity Mathematical functions have no side effects f(x) = 2x + 3 y = sin(x) Mathematical functions always give same resultfor same input Only immutable objects (and object graphs) 79. In practice All fields must be immutable All methods must return something No side-effects from method callsprintln("...") is also a side effect! 80. List head :: tail Prepends to the head of the list Other operations (filter, map, remove,partition...) returns a new List instance 81. scala.collection.immutable ...or scala.collection.mutable Pick your poison! 82. Scala 2.8 Case classes get copy methods Constructors and methods get named parametersdef resize(width: Int, height: Int) = { ... }resize(height = 42, width = 120) default parametersdef f(elems: List[Int], x: Int = 0,cond: Boolean = true)f(List(1))f(Nil, cond = false) 83. Strive to be pure Parallelization and concurrency (nosynchronization) Usually easier to find errors (a lot less state) Easier to test 84. Refactoring imperative style codedef printMultiTable () {var i = 1 // rowwhile (i 25, "z" -&gt; 26) Operations for lookup, addition/update, removal,subcollections, transformations 93. Immutable collections 94. Mutable collections 95. Higher order functions 96. Higher order functions Functions which take functions as parametersand/or return functions 97. Higher order functionsShort summary of first class functions:val even: (Int =&gt; Boolean) = (i: Int) =&gt; i % 2 == 0Same type definition:def test(numbers: List[Int], f: Int =&gt; Boolean) = ...Call:test(List(1, 2, 3), (i: Int) =&gt; i % 2 == 0) 98. Higher order functionsdef test(numbers: List[Int], f: Int =&gt; Boolean) =&gt; f(tall))// List[Boolean] 99. Higher order functionsFunctions with several parameters must list themin parenthesis:def test(l: List[String], f: (Int, String) =&gt; Boolean) 100. call-by-value vs. call-by-name by-value: expressions are evaluated beforebeing passed to the function by-name: expressions evaluated inside function nice when computationally expensive possible to create nice APIs 101. call-by-value vs. call-by-nameExample: Loggingdef thisTakesTime = {println(Slow computation)result}logger.debug(thisTakesTime()) 102. call-by-valuedef debug(s: String) {println(debug)if (logLevel String) {println(debug)if (logLevel println(reader.readLine())} 105. def using[T A) = {try {f(closeable)} finally {if (closeable != null) {try {closeable.close()}catch {case e: Exception =&gt;// Do something clever!?}}}} 106. Tasks (...</p>