Workshop Scala
Upcoming SlideShare
Loading in...5
×
 

Workshop Scala

on

  • 792 views

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!

Statistics

Views

Total Views
792
Views on SlideShare
791
Embed Views
1

Actions

Likes
1
Downloads
16
Comments
0

1 Embed 1

https://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Workshop Scala Workshop Scala Presentation Transcript

  • 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)
  • If I were to pick a language to usetoday other than Java, it would be Scala. James Gosling
  • 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
  • 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
  • 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)
  • 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)
  • String s = "!em esreveR";System.out.println(s.reverse()); val s = "!em esreveR" println(s.reverse) => Reverse me!
  • 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())}
  • I will never forget these words: "With great power comes great responsibility." This is my gift, my curse. Who am I? Im Spider-man.
  • val myList = List(1, 2, 3)val res = (10 /: myList)(_+_)=> ??
  • Scala● Object oriented and functional● Statically typed● Java compatible ● Complies to Java bytecode (and CLR) ● Existing libraries/frameworks● Better Java
  • Todays schedule● Basic syntax● REPL, IDEs and setup● First class functions● Pattern matching● OO and traits● Functional programming● Higher order functions
  • Scala basics
  • ;
  • Type definitionsScala Javas: String String si: Int int i / Integer i
  • 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;
  • Methods (3)Scala: Java:override def toString = ... @Override public String toString() {...}
  • 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; } }
  • 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
  • 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)} { ... } }
  • While-loopsScala: Java:while (true) { while (true) { ... ...} }
  • ExceptionsScala: Java:throw new throw new Exception(“...”) Exception(“...”)try { try {} catch { } catch (IOException e) { case e: IOException ... => ... } finally {} finally { }}
  • 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);
  • (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
  • GenericsScala: Java:List[String] List<String>
  • 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)
  • PackagesScala: Java:package mypackage package mypackage;... ...
  • 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}
  • REPL, IDE and setup
  • 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
  • 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
  • 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
  • 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)
  • 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.
  • First class functions
  • 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
  • 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)
  • 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
  • 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”)
  • 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
  • Pattern matching
  • myObject match { case 1 => println("First was hit") case 2 => println("Second was Hit") case _ => println("Unknown")}
  • myObject match { case i: Int => println("Found an int") case s: String => println("Found a String") case _ => println("Unknown") }
  • myObject match { case i: Int => println("Found an int") case s: String => println("Found a String") case other => println("Unknown " + other) }
  • myObject match { case i: Int if i == 1 => println("Found an int") case s: String => println("Found a String") case other => println("Unknown " + other) }
  • val res = myObject match { case i: Int if i == 1 => "Found an int" case s: String => "Found a String" case other => "Unknown " + other}
  • val res = myObject match { case (first, second) => second case (first, second, third) => third}
  • val mathedElement = list match { case List(firstElement, lastElement) => lastElement case List(firstElement, _ *) => firstElement case _ => "failed"}
  • def length(list: List[_]): Int = list match { case Nil => 0 case head :: tail => 1 + length(tail) }
  • 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}
  • Case classes● Class types that can be used in pattern matching● Generated into your class: ● equals ● hashCode ● toString ● getters (and optionally setters) ● ++
  • abstract class Person(name: String)case class Man(name: String) extends Person(name)case class Woman(name: String, children: List[Person]) extends Person(name)
  • p match { case Man(name) => println("Man with name " + name) case Woman(name, children) => println("Woman with name " + name + " and with " + children.size + " children")}
  • val regex = """(d+)(w+)""".rval myString = ...val res: String = myString match { case regex(digits, word) => digits case _ => "None"}
  • val regex = """(d+)(w+)""".rval myString = ...val res: Option[String] = myString match { case regex(digit, word) => Some(digit) case _ => None}
  • 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
  • def getValue(s: Any): Option[String]getValue(object) match { case Some(value) => println(value) case None => println("Nothing")}val result = getValue(object).getOrElse("Nothing")
  • 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
  • Object orientation and traits
  • Annotations – not marker interfaces @serializable class Person @SerialVersionUID(1) class Person @cloneable class Person @remote class Service
  • 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
  • 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)
  • Magical applyclass Person private(val age: Int)object Person { def apply(age: Int) = new Person(age)}var personInstance = Person.apply(30) personInstance = Person(30)
  • 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")
  • 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") }
  • Auxiliary constructorsclass MyClass(myString: String, myInt: Int) { def this(myString: String) = this(myString, 0) def this() = { this("foo") println("In default constructor") }}
  • Inheritanceclass MyClass(myString: String)class MySubClass(myString: String, myInt: Int) extends MyClass(myString) { println("MyString: " + myString + ", MyInt: " + myInt + "")}
  • Inheritance● Single class inheritance● Multiple trait mixins
  • Syntaxclass Person extends AnyRef with java.io.Serializable with java.rmi.Remoteclass Person extends java.io.Serializable with java.rmi.Remote
  • Traits● “Multiple inheritance done right”● Implement methods● Initialized fields● Abstract methods● Abstract fields● Abstract types● Does not have constructors● Call to super → strict semantics
  • 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}
  • 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
  • “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
  • is-a vs has-a● Inheritance as usual● Easier to implement has-a● Inheritance vs composition
  • 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
  • Functional programming
  • “Functional programming”● First class functions● Pattern matching● Higher order functions
  • 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)
  • In practice● All fields must be immutable● All methods must return something● No side-effects from method calls ● println("...") is also a side effect!
  • List● head :: tail● Prepends to the head of the list● Other operations (filter, map, remove, partition...) returns a new List instance
  • scala.collection.immutable● ...or scala.collection.mutable● Pick your poison!
  • 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)
  • Strive to be pure● Parallelization and concurrency (no synchronization)● Usually easier to find errors (a lot less state)● Easier to test
  • 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 }}
  • 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
  • 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") }
  • A closer look at Collections ● Overview of collection traitshttp://www.decodified.com/scala/collections-api.xml
  • 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/
  • 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
  • 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
  • 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
  • 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
  • Immutable collectionshttp://www.decodified.com/scala/collections-api.xml
  • Mutable collections
  • Higher order functions
  • Higher order functions● Functions which take functions as parameters and/or return functions
  • 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)
  • Higher order functionsdef test(numbers: List[Int], f: Int => Boolean) = numbers.map(tall => f(tall))// List[Boolean]
  • Higher order functionsFunctions with several parameters must list themin parenthesis:def test(l: List[String], f: (Int, String) => Boolean)
  • 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
  • call-by-value vs. call-by-nameExample: Loggingdef thisTakesTime = { println(“Slow computation”) “result”}logger.debug(thisTakesTime())
  • call-by-valuedef debug(s: String) { println(“debug”) if (logLevel <= DEBUG) println(s)}// Slow computation// debug// result
  • call-by-namedef debug(s: => String) { println(“debug”) if (logLevel <= DEBUG) println(s)}// debug// Slow computation// result
  • 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())}
  • 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!? } } }}
  • 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
  • Where to go next?
  • Advanced topics● Type inference● Implicit conversions● Extractors● Annotations● XML● Parallel programming with Actors● Domain Specific Languages (DSLs)● GUI programming with Scala Swing
  • Exercises● Solutions to exercises: http://github.com/javaBin/scala-training-code/zipball/solutions● 99 Scala Problems: http://aperiodic.net/phil/scala/s-99/
  • Berts Scala bookmarks:http://www.delicious.com/bertvv/scala
  • A lot of blogshttp://www.planetscala.com/
  • 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
  • Several books +++ http://www.scala-lang.org/node/959
  • Creative Commons http://programming-scala.labs.oreilly.com/index.html
  • http://www.scala-lang.org/
  • 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