Workshop Scala

  • 702 views
Uploaded on

I used these slides for a Scala workshop that I gave. They are based on these: http://www.scala-lang.org/node/4454. Thanks to Alf Kristian Støyle and Fredrik Vraalsen for sharing!

I used these slides for a Scala workshop that I gave. They are based on these: http://www.scala-lang.org/node/4454. Thanks to Alf Kristian Støyle and Fredrik Vraalsen for sharing!

More in: Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
702
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
22
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Scala workshop Created by Fredrik Vraalsen (fredrik@vraalsen.no) and Alf Kristian Støyle (alf.kristian@gmail.com) AdaptedBert Van Vreckem (bert.vanvreckem@hogent.be)
  • 2. If I were to pick a language to usetoday other than Java, it would be Scala. 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 term replacement 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 & Bill Venners back in 2003 Id probably 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; 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)
  • 6. 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 (kids, adults) = persons.partition(_.age < 18)
  • 7. String s = "!em esreveR";System.out.println(s.reverse()); val s = "!em esreveR" println(s.reverse) => 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 => println(reader.readLine())}
  • 9. I will never forget these words: "With great power comes 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)(_+_)=> ??
  • 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: Int int 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 = ... @Override public String toString() {...}
  • 18. Classes and constructorsScala: Java:class Person(val name: public class Person { String) private final String name; public Person(String name) { this.name = name; } public String getName() { return name; } }
  • 19. Traits (= Interface + Mixin)Scala: Java:trait Shape { interface Shape { def area: Double public double area();} }class Circle extends Object public class Circle extends with Shape Object implements Shape
  • 20. No “static” in ScalaScala: Java:object PersonUtil { public class PersonUtil { val ageLimit = 18 public static final int AGE_LIMIT = 18; def countPersons( public static int persons: List[Person]) = countPersons( ... List<Person> persons)} { ... } }
  • 21. While-loopsScala: Java:while (true) { while (true) { ... ...} }
  • 22. ExceptionsScala: Java:throw new throw new Exception(“...”) Exception(“...”)try { try {} catch { } catch (IOException e) { case e: IOException ... => ... } 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 <- 1 to 10) yield i // List(1, ..., 10)val res = try { x } catch { ...; y } finally { } // x or y
  • 25. GenericsScala: Java:List[String] List<String>
  • 26. TuplesScala: Java:val tuple: Tuple2[Int, Pair<Integer, String> tuple String] = = new Pair<Integer, String>(1, “apple”) (1, “apple”)val quadruple = ... yeah right... ;-) (2, “orange”, 0.5d, false)
  • 27. PackagesScala: Java:package mypackage package mypackage;... ...
  • 28. ImportsScala: Java:import java.util.{List, import java.util.List ArrayList} import java.util.ArrayListimport java.io._ import java.io.*import scala.util.Sorting._ ???import java.sql.{Date => ??? SDate}
  • 29. REPL, IDE and setup
  • 30. REPL: Read-Eval-Print Loop● Command line shell for on-the-fly execution of Scala 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 !#$&§? compared to what you are used 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 when working
  • 32. Netbeans 6.9.x installation● Download plugins http://sf.net/projects/erlybird/files/nb-scala/6.9v1.1.0/● 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: http://wiki.netbeans.org/Scala
  • 33. Tasks (20 min)● Run REPL ● Windows: %scala_home%/bin/scala ● Linux: scala or /opt/scala/bin/scala ● Execute a few statements● Copy & unpack HeliumPublicCursussenNavorming ScalaScalaTraining.zip ● 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.scala print “Hello world”. What is the difference?● Remove comments from @Test for the methods in scalaexamples/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 => Boolean) = (i: Int) => i % 2 == 0val even = (i: Int) => 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) => i > 2) // List(3, 4, 5)numbers.filter(i => i > 2) // List(3, 4, 5)numbers.filter(_ > 2) // List(3, 4, 5)
  • 38. Collectionsnumbers.filter(i => i > 2) // List(3, 4, 5)numbers.find(i => i > 2) // Some(3)numbers.exists(i => i > 2) // truenumbers.forall(i => i > 2) // falsenumbers.map(i => i * 2) // List(2, 4, 6, 8, 10)numbers.foldLeft(0) { (a, b) => a + b } // 15
  • 39. Closuresval people = List(Person(“Alf”), Person(“Fredrik”))var name = “Fredrik”val nameFilter = (p: Person) => p.name == namepeople.filter(nameFilter) // Person(“Fredrik”)name = “Alf”people.filter(nameFilter) // Person(“Alf”)
  • 40. Tasks (30 min)● Open the first-class-functions project● Tests in package scalaexamples.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 => println("First was hit") case 2 => println("Second was Hit") case _ => println("Unknown")}
  • 43. myObject match { case i: Int => println("Found an int") case s: String => println("Found a String") case _ => println("Unknown") }
  • 44. myObject match { case i: Int => println("Found an int") case s: String => println("Found a String") case other => println("Unknown " + other) }
  • 45. myObject match { case i: Int if i == 1 => println("Found an int") case s: String => println("Found a String") case other => println("Unknown " + other) }
  • 46. val res = myObject match { case i: Int if i == 1 => "Found an int" case s: String => "Found a String" case other => "Unknown " + other}
  • 47. val res = myObject match { case (first, second) => second case (first, second, third) => third}
  • 48. val mathedElement = list match { case List(firstElement, lastElement) => lastElement case List(firstElement, _ *) => firstElement case _ => "failed"}
  • 49. def length(list: List[_]): Int = list match { case Nil => 0 case head :: tail => 1 + length(tail) }
  • 50. public static Integer getSecondOr0(List<Integer> list) { if (list != null && list.size() >= 2) { return list.get(1); } else { return 0; }}def second_or_0(list:List[Int]) = list match { case List(_, x, _*) => x case _ => 0}
  • 51. Case classes● Class types that can be used in pattern matching● 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) => println("Man with name " + name) case Woman(name, children) => 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) => digits case _ => "None"}
  • 55. val regex = """(d+)(w+)""".rval myString = ...val res: Option[String] = myString match { case regex(digit, word) => Some(digit) case _ => None}
  • 56. The Option type, never again NullPointerException● Option has two possible values ● Some(value) ● None val someOption: Option[String] = Some("value") val noOption: Option[String] = None
  • 57. def getValue(s: Any): Option[String]getValue(object) match { case Some(value) => println(value) case None => println("Nothing")}val result = getValue(object).getOrElse("Nothing")
  • 58. Tasks (30 min)● Open the pattern-matching project● Tests in package scalaexamples.patternmatching● Add @Test to one and one method● Follow instructions in the code● Make the tests pass
  • 59. Object orientation and traits
  • 60. Annotations – not marker interfaces @serializable class Person @SerialVersionUID(1) class Person @cloneable class Person @remote class Service
  • 61. object● object is a “singleton” class ● Call may look like static method calls in Java ● Can inherit from other classes and traits ● Can be passed as a reference object MyObject { def foo = "bar" } var baz = MyObject.foo val personObject = MyObject baz = personObject.foo
  • 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 -> "one", 2 -> "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 primary constructor class MyClass(myString: String, myInt: Int) val myOtherInt = 10 println("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 java.io.Serializable with java.rmi.Remoteclass Person extends java.io.Serializable 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): Int def < (that: A): Boolean = (this compare that) < 0 def > (that: A): Boolean = (this compare that) > 0 def <= (that: A): Boolean = (this compare that) <= 0 def >= (that: A): Boolean = (this compare that) >= 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 < person2 // trueperson1 <= person2 // trueperson1 >= person2 // false
  • 73. “Dynamic mixins”class 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)=> 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 result for 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 calls ● println("...") 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 parameters def resize(width: Int, height: Int) = { ... } resize(height = 42, width = 120) ● default parameters def 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 (no synchronization)● Usually easier to find errors (a lot less state)● Easier to test
  • 84. Refactoring imperative style codedef printMultiTable () { var i = 1 // row while (i <= 10) { var j = 1 // column while (j <= 10) { val prod = (i * j).toString var k = prod.length // padding while (k < 4) { 1 2 3 4 5 6 7 8 9 10 print(" ") 2 4 6 8 10 12 14 16 18 20 k += 1 3 6 9 12 15 18 21 24 27 30 } 4 8 12 16 20 24 28 32 36 40 print(prod) 5 10 15 20 25 30 35 40 45 50 j += 1 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 } 8 16 24 32 40 48 56 64 72 80 println() 9 18 27 36 45 54 63 72 81 90 i += 1 10 20 30 40 50 60 70 80 90 100 }}
  • 85. Refactoring imperative style code● Side effect: printing table ● Functional style: return String● Harder to test ● How to test result of println()?● While loop & vars ● Functional style: val, for expressions, helper functions ● Helper functions can be tested separately
  • 86. Functional style multiplication table def makeRowSeq(row: Int) = for (col <- 1 to 10) yield { val prod = (row * col).toString val padding = " " * (4 - prod.length) padding + prod } def makeRow(row: Int) = makeRowSeq(row).mkString def multiTable = { val tableSeq = for (row <- 1 to 10) yield makeRow(row) tableSeq.mkString("n") }
  • 87. A closer look at Collections ● Overview of collection traitshttp://www.decodified.com/scala/collections-api.xml
  • 88. Traversable● One abstract method: def foreach[U](f: Elem => U)● 50+ concrete methods ● Addition, mapping, conversion, copying, size info, element retrieval, sub-collection retrieval, subdivision, element tests, folds, string operations, view http://www.scala-lang.org/api/ http://www.scala-lang.org/docu/files/collections-api/
  • 89. Iterable● Abstract method iterator● Default implementation of foreach: def foreach[U](f:Elem => U): Unit = { val it = iterator while (it.hasNext) f(it.next()) } ● Subclasses may override● Some concrete methods ● Subcollections, "zippers", comparison
  • 90. Seq, IndexedSeq, LinearSeq● Sequence: ● iterable that has a length, ● elements have fixed index position, starting with 0● Operations: ● Indexing (apply), search, addition, update, sorting, reversal, comparison, set operations● IndexedSeq, LinearSeq ● No new operations, but different performance – LinearSeq: efficient head, tail – IndexedSeq: efficient apply, length
  • 91. Sets, SortedSet● Set = iterable that contain no duplicates ● Operations for tests, addition, removal, set operations● SortedSet ● Iterator/foreach visit elements in given ordering ● Default implementation: binary tree
  • 92. Maps● Map = collection of pairs of keys and values e.g. Map("x" -> 24, "y" -> 25, "z" -> 26) ● Operations for lookup, addition/update, removal, subcollections, transformations
  • 93. Immutable collectionshttp://www.decodified.com/scala/collections-api.xml
  • 94. Mutable collections
  • 95. Higher order functions
  • 96. Higher order functions● Functions which take functions as parameters and/or return functions
  • 97. Higher order functionsShort summary of first class functions:val even: (Int => Boolean) = (i: Int) => i % 2 == 0Same type definition:def test(numbers: List[Int], f: Int => Boolean) = ...Call:test(List(1, 2, 3), (i: Int) => i % 2 == 0)
  • 98. Higher order functionsdef test(numbers: List[Int], f: Int => Boolean) = numbers.map(tall => f(tall))// List[Boolean]
  • 99. Higher order functionsFunctions with several parameters must list themin parenthesis:def test(l: List[String], f: (Int, String) => Boolean)
  • 100. 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
  • 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 <= DEBUG) println(s)}// Slow computation// debug// result
  • 103. call-by-namedef debug(s: => String) { println(“debug”) if (logLevel <= DEBUG) println(s)}// debug// Slow computation// result
  • 104. 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 => println(reader.readLine())}
  • 105. 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 => // Do something clever!? } } }}
  • 106. Tasks (30 min)● Open higher-order-functions project● Tests in scalaexamples.higherorderfunctions● Add @Test to one and one method● Implement missing functions in PersonFilter and so on.● Follow instructions in code● Make tests pass
  • 107. Where to go next?
  • 108. Advanced topics● Type inference● Implicit conversions● Extractors● Annotations● XML● Parallel programming with Actors● Domain Specific Languages (DSLs)● GUI programming with Scala Swing
  • 109. Exercises● Solutions to exercises: http://github.com/javaBin/scala-training-code/zipball/solutions● 99 Scala Problems: http://aperiodic.net/phil/scala/s-99/
  • 110. Berts Scala bookmarks:http://www.delicious.com/bertvv/scala
  • 111. A lot of blogshttp://www.planetscala.com/
  • 112. Mailing lists scala@listes.epfl.ch scala-announce@listes.epfl.ch scala-user@listes.epfl.ch scala-debate@listes.epfl.ch scala-tools@listes.epfl.ch scala-internals@listes.epfl.chhttp://www.scala-lang.org/node/199
  • 113. Several books +++ http://www.scala-lang.org/node/959
  • 114. Creative Commons http://programming-scala.labs.oreilly.com/index.html
  • 115. http://www.scala-lang.org/
  • 116. Creative Commons Attribution 3.0 Unported Scala Training Code http://github.com/javaBin/scala-training-code git clone git://github.com/javaBin/scala-training-code Scala Training Slides http://github.com/javaBin/scala-training-slidesgit clone git://github.com/javaBin/scala-training-slides.git