KEMBAR78
Oop2010 Scala Presentation Stal | PPTX
Introduction toCoding in Scala is fun!OOP 2010Dr. Michael StalMichael.Stal@siemens.com
Objectives of this PresentationIntroduce core concepts of ScalaShowing you the benefits of combining OO with functional programmingIllustrating the language in a pragmatic way preferring code over theoryBut not to cover every available aspect or to cover aspects in full  detailFor instance, we won‘t cover Java/Scala Interop, Views, Equality Semantics, Unit Testing, AnnotationsPage 2
IntroductionScala created by the team of Martin Odersky at EPFL„Scala“ means „Scalable Language“„Scalable“ means: the same language concepts for programming in the small & largeIn Scala this is achieved in a pragmatic way by combining Object Oriented Programming withFunctional Programming Scala is a statically typed language like JavaAll types are objectsPage 3Martin Odersky, Source: http://lamp.epfl.ch/~odersky/
Object-Oriented & Functional ProgrammingObject-Oriented ProgrammingAbstraction using Classes and InterfacesRefinement using subtyping and inheritance (Remember the Liskov Substitution Principle!)Dynamics through polymorphismFunctional ProgrammingHigher Order Functions as First-Class EntitiesADTs (Abstract Data Types) following algebraic conventionsPattern matchingParametric polymorphism (generic types)Page 4SCALA
Core Properties of Scala (see Programming in Scala)Scala is compatible: runs on JVM, interoperability with JavaScala is concise: More compact code because removal of Java boilerplate code and powerful librariesScala is high-level: Higher level of abstraction by combining OO with functional programmingScala is statically typedPage 5Scala‘s Roots: Java, C#
 Smalltalk, Ruby
 Beta, Simula, Algol
 ML
 ErlangA small Appetizer - Hello, Scala!Page 6Type InferenceImmutable valuesClassesclass HelloWorldClass (val name: String) {	def print() = println("Hello World of " + name)}object HelloWorldMain {  	def main(args: Array[String]): Unit = {val hello = new HelloWorldClass("Scala")    		hello print  	}}=> Hello World of ScalaSingletonsLook Ma, no semicolonsNo brackets required!
Stairway to Heaven – First Steps using Scala This source code file may be compiled using scalac und run using scala:scalac HelloWorldMain.scalascala HelloWorldMain Note: the source file must be named like the main object to be executed You may run an interpreter by using the following command line insteadscala HelloWorldMain.scala In this case you may also use plain Scala scripts (no classes or objects required)Or, even better, you might use an IDE like Idea, Netbeans, or EclipsePage 7
A more advanced example (1)  (from Venkat Subramanian‘s book Programming Scala, pp.5)Page 8import scala.actors._import Actor._val symbols = List( "AAPL", "GOOG", "IBM", "JAVA", "MSFT")val receiver = selfval year = 2009symbols.foreach {   symbol =>  actor { receiver ! getYearEndClosing(symbol, year) }}val (topStock, highestPrice) = getTopStock(symbols.length)printf("Top stock of %d is %s closing at price %f\n", year, topStock, highestPrice)def getYearEndClosing(symbol : String, year : Int) = {    val url = new       java.net.URL("http://ichart.finance.yahoo.com/table.csv?s=" +    symbol + "&a=11&b=01&c=" + year + "&d=11&e=31&f=" + year + "&g=m")        val data = io.Source.fromURL(url).mkString    val price = data.split("\n")(1).split(",")(4).toDouble      (symbol, price)} // .. to be continued
A more advanced example (2)(from Venkat Subramanian‘s book Programming Scala, pp.5)Run this within interpreter mode scala TopScala.scalaAfter the end of the talk return to this example and check whether you better understand itPage 9// continued ...def getTopStock(count : Int) : (String, Double) = {     (1 to count).foldLeft("", 0.0) { (previousHigh, index) =>         receiveWithin(10000) {             case (symbol : String, price : Double) =>                   if (price > previousHigh._2) (symbol, price)            else previousHigh         }     }} // will result in =>// Top stock of 2009 is GOOG closing at price 619,980000
Scala Type HierarchyPage 10Scala uses a pure object-oriented type systemEvery value is an objectTwo types: values and referencesAny is parent class of all classes, Nothing subclass of all classesBasictypes like inJavaSource: Scala Reference Manual
First Class ScalaPage 11born and id will bepublic fieldsMain constructorClasses in Scala contain fields, methods, types, constructorsVisibility is public per defaultclass CatID(val id : Int)  //that's a whole classclass Cat(val born: Int, val id: CatID) {private var miceEaten: Int = 0   def digested() = miceEatendef hunt(miceCaught: Int)              { miceEaten +=  miceCaught }}object ScalaClasses {   def main(args: Array[String]) {     val id = new CatID(42)     val tom = new Cat(2010, id)     tom.hunt(3)     tom hunt 2     println(“cat was born in “ + tom.born)      println(tom.digested)   }} // => 5 <\n> Tom was born in 2010 definitionof methodsNo bracketsrequired
Class ConstructorsPage 12class Complex (r : Double, i: Double) {  println("Constructing a complex number")  val re = r  val im = i  def this(r : Double) = this(r,0)  override def toString =         re + (if (im < 0) "-" + (-im)              else "+" + im) + "*i"  ...}Belongs toPrimaryconstructorAuxilliaryconstructorsmust callprimary
Immutable and Mutable ObjectsScala provides immutable objects (functional programming) but also mutable objectsImmutability has many benefitsReduction of race conditions in concurrent programsProtection against unwanted modificationScala provides mutable & immutable versions of collection typesMutable objects are important to address objects that are supposed to change their state, but use them with carePage 13class Person(var name: String)object ImmutabilityDemo { def main(args:Array[String]) = {val s = "Michael"   s = "Bill" // errorvar t = "Michael“ // t variable   t = "Bill" // ok   val c = new Person("Bill")   c = new Person("Tom") // error// ok - c itself unchanged:   c.name = "Tom" }}
InheritanceIn Scala classes can be derived from at most one base classClasses may be abstractYou need to indicate whether you override inherited methodsPage 14abstractclass Shape {type Identifier = Int // defining types  def getID() : Identifier = 42  def draw() : String   // abstract method}class Circle (val cx: Double, val cy: Double, val r: Double) extends Shape {  val id : Identifier = getID()override def draw() : String = "I am a Circle"}
Companion Objects and Standalone ObjectsWe already saw standalone objectsObjects are singletonsIf you need static fields or methods for a class, introduce a companion class with the same nameConvention: apply() methods may be provided as factory methodsPage 15class Cat private (val born : Int, val id: CatID) {   ...private def this(id: CatID) = this(2010, id)   ...} // all constructors are privateobject Cat { // this is the companion object of Catdef apply(born: Int, id: CatID) =  new Cat(born, id)   def apply(id: CatID) = new Cat(id) // factory method   def whatCatsDo() = "Sleep, eat, play"	}object ScalaClasses { // Standalone Object   def main(args: Array[String]) {     val id = new CatID(43)val pussy = Cat(id) // no new required     println("Pussy was born in " + pussy.born)     println(Cat.whatCatsDo)  // like static in Java     }}
Application Base ClassFor experimenting with Scala use the base class ApplicationJust compile this with: scalac ObjDemo.scalaAnd run it with: scala ObjDemoUseful abbreviation if you do not need to deal with command line argumentsPage 16  Inheritanceobject ObjDemoextends Application {val s: String = "Michael"println(s) // => Michael}
TraitsClasses and instances may mix-in additional functionality using traitsTraits represent an abstraction between interfaces and classesUsing traits we can easily live with the single-inheritance restrictionYou may use also traits via anonymous classes:	val x = new Identity{}  	x.name = "UFO"  	println(x.whoAmI)Page 17trait   Identity  {   var name: String=""   def whoAmI() : String = name	}class  Person extends Identity class Animalobject TraitDemo { def main(args:Array[String]) = {   val p = new Person   p.name = "Michael"   println(p.whoAmI)val a = new Animal with Identity   a.name = "Kittie"   println(a.whoAmI) }} // => Michael <\n> Kittie
Traits and Virtual Super: Inheritance LinearizationPage 18abstract class Processor { def process() }trait Compressor extends Processor { // trait only applicable to Processor subclassabstract override def process() =  { println("I am compressing"); super.process }}trait Encryptor extends Processor { // only applicable to Processor subclassabstract override def process() = { println("I am encrypting"); super.process}}class SampleProcessor extends Processor { // subclass of Processor    override def process() = println("I am a Sample Processor")}object traitsample2 {    def main(args:Array[String]) = { // mixing in a trait to an object:val proc1 = new SampleProcessor with Compressor with Encryptorproc1.process// Encryptor.process=>Compressor.process     }                        //                                   => SampleProcessor.process}Note: abstract override for a trait method means the actual subclass of Processor will provide a concrete implementation of that method!
Scala Basics: if StatementsIf statements are expressions themselves, i.e. they have valuesPage 19import java.util._if (1 + 1 == 3) println(“strange world”) else {println(“everything’s ok”)}val res = if ((new Random().nextInt(6) + 1) == 6) 		"You win!" 	    else             "You lose!"
Scala Basics: for Comprehensions (1)A for comprehension is like a for loop. It lets you traverse a collection, return every object in a temporary variable which is then passed to an expression. You may also specify nested iterations:You can specify filters for the collection elementsPage 20val aList  = List(1,2,3,4,5,6)for (i <- aList) println(i) // => 1 <\n> 2 ...val dogs = Set("Lassie", "Lucy", "Rex", "Prince");for (a <- dogs if a.contains("L")) println(a)// => “Lassie” <\n> “Lucy”
Scala Basics: for Comprehensions (2)Yield allows to create new collections in a for comprehension:You can specify filters for the collection elementsPage 21var newSet = for {                   a <- dogs                   if a.startsWith("L")             } yield aprintln(newSet)  // Set(Lassie, Lucy)for {     i <- List(1,2,3,4,5,6)    j = i * 2 // new variable j defined} println(j) // => 2 <\n> 4 <\n> 6 ...
Scala Basics: Other loopsScala supports while and do-while loopsBut generator expressions such as (1 to 6)  incl. 6 or (1 until 6) excl. 6 together with for make this much easierNote: The reason this works is a conversion to RichInt where to is defined as a method that returns an object of type Range.Inclusive, an inner class of Range implementing for comprehensionsPage 22var i = 1while (i <= 6)  {    println(i)    i  += 1} // = 1 <\n> 2 <\n> 3 ... for (i <- 1 to 6) println(i)
Scala Basics: Exception handlingtry-catch-finally available in Scala but throws isn‘tcatching checked exceptions is optional!catch-order important as in Java, C++ or C#Page 23def temperature(f: Double) {  if (f < 0) throw new IllegalArgumentException()}try {   println("acquiring resources")   temperature(-5)}catch {   case ex:  IllegalArgumentException => println("temperatur < 0!")   case _ => println("unexpected problem")}finally {   println("releasing resources")}
Inner ClassesYou may define inner classes as in JavaSpecial notation (<name> =>)  for referring to outer class this from an inner class: you might also use <outerclass>.this insteadPage 24class Element (val id: String){ elem =>class Properties { // inner classtype KV = Tuple2[String, Any]    var props: List[KV] = Nil    def add(entry: KV) { props = entry :: props }    override def toString = {      var s: String = ""      for (p <- properties.props) s = s + p +"\n"      s    }}  override def toString = "ID = " + id + "\n" + properties  val properties = new Properties  }object InnerClassDemo extends Application {  val e = new Element("Window")  e.properties.add("Color", "Red")  e.properties.add("Version", 42)  println(e.toString)}
Imports and PackagesWe can partition Scala definitions into packages:A package is a special object which defines a set of member classes, objects and packages. Unlike other objects, packages are not introduced by a definitionImporting packages works via import statements – almost like in JavaPackages scala, java.lang, scala.Predefare automatically importedPage 25package MyPackage1 {   class Person(val name: String)   class Animal(val name: String)}import MyPackage1._object PacDemo extends Application {   val person = new Person("Michael")   println(person name)} import p._              all members of p (this is analogous                                    to import p.* in Java).  import p.x              the member x of p.
 import p.{x => a}   the member x of p renamed as a.
 import p.{x, y}       the members x and y of p.
 import p1.p2.z       the member z of p2, itself member of p1.Advanced Types: ListsCollection Type: ListPage 26object ListDemo { def main(args:Array[String]) {   val l1 : List[Int] = Nil // empty List   val l2 = List[Int](1,2,3,4,5) // list with 5 elements   val l3 = 0 :: l2 // add 0 to the list   val l4 = List[Int](0,1,2) :::  List[Int](3,4,5) // concat 2 lists   println("Top Element:  " + l4.head) // => 0   println("Rest of list: " + l4.tail) // => List(1,2,3,4,5)   println("Last Element: " + l4.last) // => 5l4.foreach { i => println(i) } // => 1 <\n> 2 <\n> 3 ... }}Foreach traverses a list and passes each element found to the closure passed as argument
Advanced Types: SetsCollection Type: SetPage 27object SetDemo { def main(args:Array[String]) {val s1 = Set[Int](1,2,3,4,5) // we could also use = Set(1,2,3,4,5)val s2 = Set[Int](2,3,5,7)println(s2.contains(3))  // => trueval s3 = s1 ++ s2 // unionprintln(s3) // => Set(5,7,3,1,4,2)vals4 = s1 & s2 // intersection: in earlier versions **println(s4) // Set(5,3,2)  }}
Advanced Types: MapsCollection Type: MapPage 28object MapDemo { def main(args:Array[String]) {val m1 = Map[Int, String](1 -> "Scala", 2->"Java", 3->"Clojure")valm2 = m1 + (4 -> "C#") // add entryprintln(m2 + " has size " + m2.size)                            //=> Map(1->Scala,…) has size 4println(m1(1)) // => Scalaval m3 = m2 filter { element => val (key, value) = element                    (value contains "a") }  println(m3) // => Map(1->Scala, w->Java) }}
Advanced Types: Optionsobject DayOfWeek extends Enumeration {  val Monday    = Value("Monday") //argument optional   val Sunday    = Value("Sunday") //argument optional }import DayOfWeek._ object OptionDemo { def whatIDo(day: DayOfWeek.Value) : Option[String] =     {    day match {      case Monday  => Some("Working hard")      case Sunday  => None    } } def main(args:Array[String]) {   println(whatIDo(DayOfWeek.Monday))    println(whatIDo(DayOfWeek.Sunday))  } //=> Some(„Working Hard“) <\n> None}The Option type helps dealing with optional valuesFor instance, a search operation might return  a result or nothingWe are also introducing EnumerationtypesPage 29
Advanced Types: Regular ExpressionsType: Regex introduces well-known regular expressionsPage 30With this syntax strings remain formatted as specified and escape sequences are not requiredobject RegDemo { def main(args:Array[String]) {val pattern = """\d\d\.\d\d\.\d\d\d\d""".rval sentence = “X was born on 01.01.2000 ?"println (pattern findFirstIn sentence) // => Some(01.01.2000) }}Note: the „r“ in “““<string>“““.r means: regular expression
Advanced Types: TuplesTuples combine fixed number of Elements of various typesThus, you are freed from creating heavy-weight classes for  simple aggregatesPage 31println( (1, "Douglas Adams", true) )def goodBook = {("Douglas Adams", 42, "Hitchhiker's Guide")}        println ( goodBook._3 ) // get third element// => (1, Douglas Adams, true)// => Hitchhiker‘s Guide
Advanced Types: ArraysArrays hold sequences of elementsAccess very efficientPage 32val a1 = new Array[Int](5) // initialized with zeros val a2 = Array(1,2,3,4,5) // initialized with 1,2,3,4,5println( a2(1) ) // => 2a2(1) = 1 // => Array (1,1,3,4,5)Note:In Scala the assignment operator = does not return a reference to the left variable (e.g., in a = b).Thus, the following is allowed in Java but not in Scala: a = b = c
Smooth OperatorIn Scala operator symbols are just plain method names For instance 1 + 2 stands for 1.+(2)Precedence rules:All letters|^&<  >=  !:+  -*  /  %Page 33class Complex(val re:Double, val im:Double) {def +(that: Complex) : Complex = {     new Complex(this.re + that.re,                  this.im + that.im)   }   override def toString() : String = {     re + (if (im < 0) "" else "+") + im +"i"   }}object Operators {  def main(args: Array[String]) {        val c1 = new Complex(1.0, 1.0)        val c2 = new Complex(2.0, 1.0)        println(c1+c2)  }} // => (3.0+2.0i)
ConversionsImplicit converters allow Scala to automatically convert data typesSuppose, you‘d like to introduce a mathematical notatation such as 10! Using implicit type converters you can easily achieve thisPage 34object Factorial {  def fac(n: Int): BigInt =    if (n == 0) 1 else fac(n-1) * n  class Factorizer(n: Int) {def ! = fac(n)  }implicit def int2fac(n: Int) = new Factorizer(n)}import Factorial._object ConvDemo extends Application {println("8! = " + (8!)) // 8 will be implicitly converted} // => 40320
Parameterized Types in ScalaClasses, Traits, Functions may be parameterized with typesIn contrast to Java no wildcards permitted – parameter types must have namesVariance specification allow to specify covariance and contravariancePage 35trait MyTrait[S,T] {  def print(s:S, t:T) : String = "(" + s  + "," + t + ")"}class MyPair[S,T] (val s : S, val t : T) extends MyTrait [S,T] {  override def toString() : String = print(s,t)	}object Generics {  def main(args: Array[String]) {	val m = new MyPair[Int,Int](1,1)	printf(m.toString())  }} // => (1,1)
Small Detour to Variance and Covariance / Type BoundsIf X[T] is a parameterized type and T an immutable type:X[T] is covariant in T if:	S subTypeOf T => X[S] subTypeOf  X[T]X[T] is contravariant in T if:  	S subTypeOf T => X[S] superTypeOf X[T]In Scala covariance is expressed as X[+T] and contravariance with X[-T]Covariance is not always what you want: Intuitively we could assign a set of apples to a set of fruits. However, to a set of fruits we can add an orange.  The original set of apples gets „corrupted“ this wayExample List[+T]: Covariance means a List[Int] can be assigned to a List[Any] because Int is subtype of AnyUpper/Lower Bounds may be specified:In the following example D must be supertype of S:	def copy[S, D>:S](src: Array[S], dst: Array[D]) = { ...Page 36
Functional Aspects: Functions and ClosuresIn Scala Functions are First-Class CitizensThey can be passed as argumentsassigned to variables:           val closure={i:Int => i+42}Nested functions are also supportedPage 37object scalafunctions {  def add(left:Int,right:Int, code:Int=>Int)=  {var res = 0     for (i<-left to right) res += code(i)     res  }  def main(args: Array[String]) {println(add(0,10, i => i))println(add(10,20, i => i % 2  ))  }}=>555
Functional Aspects: Call-by-NameIf a parameterless closure is passed as an argument to a function, Scala will evaluate the argument when the argument is actually usedThis is in contrast to call-by-value argumentsA similar effect can be achieved using lazy (value) evaluation:     lazy val = <expr>       Page 38import java.util._object CbNDemo {def fun(v: => Int) : Int = v  // v is a Call-by-Name Parameterdef v() : Int = new Random().nextInt(1000) def main(args:Array[String]) {   println( fun(v) )   println( fun(v) )   }} // => 123 <\n> 243
Functional Aspects: Currying (1)Currying means to transform a function with multiple arguments to a nested call of functions with one (or more) argument(s)def fun(i:Int)(j:Int) {}   (Int)=>(Int)=>Unit=<function1>Page 39object scalafunctions {   def fun1(i:Int, j:Int) : Int = i + jdef fun2(i:Int)(j:Int) : Int = i + j     def main(args: Array[String]) {	println(fun1(2,3))	println(fun2(2){3})	println(fun2{2}{3} )   }}  // => 5 5 5
Functional Aspects: Currying (2)Currying helps increase readabilityTake foldleft as an examplePage 40FoldLeft Operatorval x =  (0 /: (1 to 10)) { (sum, elem) => sum + elem } // 55 Carryover value for next iterationFunction argumentsCarryover valueCollectionFor each iteration, foldleft passes the carry over value and the current collection element. We need to provide the operation to be appliedThis is collection which we iterate overThis is the value that is updated in each iterationThink how this would be implemented in Java!
Positional ParametersIf you use a parameter only once, you can use positional notation of parameters with _ (underscore) insteadPage 41object scalafunctions { def main(args:Array[String]) {	val seq= (1 to 10)	println( (0 /: seq) { (sum, elem) => sum + elem } )	println( (0 /: seq) { _ + _ } )  }	}
Using the features we can build new DSLs and additional features easilyThe following loop-unless example is from the Scala tutorial Page 42object TargetTest2 extends Application {def loop(body: => Unit): LoopUnlessCond =    new LoopUnlessCond(body)protected class LoopUnlessCond(body: => Unit) {    def unless(cond: => Boolean) {      body      if (!cond) unless(cond)    }  }  var i = 10   loop {    println("i = " + i)    i -= 1  } unless (i == 0)}We are calling loopwith this body ...and invoking unlesson the result
Functional Aspect: Partially Applied FunctionsIf you only provide a subset of arguments to a function call, you actually retrieve a partially defined functionOnly the passed arguments are bound, all others are notIn a call to a partially applied function you need to pass the unbound argumentsAll this is useful to leverage the DRY principle when passing the same arguments again and againPage 43object scalafunctions {  def fun(a : Int, b : Int, c:Int) = a+b+c  def main(args: Array[String]) {val partialFun = fun(1,2,_:Int)	  println( partialFun(3) ) // 6	  println( partialFun(4) ) // 7	}}
Functions Are Objects Function: S => T trait Function1[-S,+T] {     def apply(x:S):T   }Example:  (x: Int) => x * 2-> new Function1[Int,Int] {     def apply(X:Int):Int = x * 2   }In Scala all function values are objectsBasically, each function is identical to a class with an apply methodThus, you can even derive subclasses from functionsArray is an example for this: class Array [T] (length: Int ) extends (Int => T)  {def length: Int = ...Page 44
Functional Aspects: Pattern MatchingPattern matching allows to make a  pragmatic choice between various optionsPage 45valaNumber = new Random().nextInt(6) + 1;aNumbermatch {case 6 => println("You got a 6")case 1 => println("You got a 1");caseotherNumber => println("It is a " + otherNumber)}
Functional Aspects: Matching on TypesIt is also possible to differentiate by type:Page 46object TypeCase {   def matcher(a: Any) {a match {	   case i : Int if (i == 42) => println("42")	   case j : Int => println("Another int")	   case s : String => println(s)	   case _  => println("Something else")        }   }   def main(args: Array[String]) {	matcher(42)	matcher(1)	matcher("OOP")	matcher(1.3)	   }} // => 41 <\n> 1  <\n> OOP <\n> Something else
Functional Aspects: Matching on ListsLists can be easily used with Pattern Matching:Page 47object ListCase {   def matcher(l: List[Int]) {l match {	   case List(1,2,3,5,7) => println("Primes")	   case List(_,_,_3,_) => println("3 on 3");	   case 1::rest => println("List with starting 1");	   case List(_*) => println("Other List");        }   }   def main(args: Array[String]) {	matcher(List(1,2,3,5,7))	matcher(List(5,4,3,2))	matcher(List(1,4,5,6,7,8));	matcher(List(42))   }} => Primes <\n> 3 on 3 <\n> List with starting 1 <\n> Other List
Functional Aspects: Matching on TuplesSo do Tuples:Page 48object TupleCase {   def matcher(t : Tuple2[String,String]) {t match {	   	case ("OOP",s) => println("OOP " + s)  		case ("Scala", s) => println("Scala " + s)	   	case _ => println("Other Tuple")        }   }   def main(args: Array[String]) {	matcher("OOP", "2010")	matcher("Scala", "rocks");	matcher("A","B")   }} => OOP 2010 <\n> Scala rocks >cr> Other Tuple
Functional Aspects: Matching on Case ClassesCase Classes are classes for which the compiler generates additional functionality to enable pattern matching, e.g., an apply() method:Page 49sealed abstract class Shape // sealed => subclasses only in this source filecase class Circle(val center: Point, val radius: Double) extends Shapecase class Line(val pt1: Point, val pt2: Point) extends Shapecase class Point (val x:Double, val y:Double){   override def toString() = "(" + x +"," + y + ")" }object CaseClasses {   def matcher(s : Shape) {s match {	   case Circle(c, r) => println(“Circle“ :  + c +  “ “ + r)	   case Line(p1, p2) => println("Line " + p1 + " : " + p2) 	   case _ => println("Unknown shape")        }   }   def main(args: Array[String]) {	matcher(Circle(Point(1.0, 1.0), 2.0))	matcher(Line(Point(1.0, 1.0), Point(2.0, 2.0)))   }}
Functional Aspect: ExtractorsExtractors are objects with an unapply method used to match a value and partition it into constituents – an optional apply is used for synthesisPage 50object EMail {  def apply(prefix: String, domain: String) = prefix + "@" + domaindef unapply(s: String): Option[(String,String)] = {   val parts = s split "@"   if (parts.length == 2) Some(parts(0), parts(1)) else None  } }object scalafunctions { def main(args:Array[String]) {   val s = "michael.stal@siemens.com"   s match {      case EMail(user, domain) => println(user + " AT " + domain)     case _ => println("Invalid e-mail")   }  }	}
Partial Functions Partial Functions are not defined for all domain valuesCan be asked with isDefinedAt whether a domain value is acceptedExample: Blocks of Pattern Matching CasesPage 51trait PartialFunction[-D, +T] extends (D => T) {  def isDefinedAt(x: D): Boolean}
ActorsActors have been introduced in the 1970s:the Actor model is a mathematical model of concurrent computationthat treats "actors" as the universal primitives of concurrent digital computation: in response to a message that it receives, an actor can make local decisions, create more actors, send more messages, and determine how to respond to the next message received. [Hewitt, 73]Page 52Also available in Erlang, Axum, Io, ClojureProvided as library implementation in Scala (demonstrating Scala‘s capability of providing internal DSLs)
Actor ClassesClass Actor requires to override act() which is the functionality executed by a threadYou may also instantiate anonymous actors in a much more convenient way:Page 53import scala.actors.Actorclass VolcanextendsActor {def act() {println(“thinking ...")  }}object SpockRunner {  def main(args:Array[String]) = {valspock = new Volcanspock start  }}import scala.actors.Actorimport Actor._object SpockRunner {  def main(args:Array[String]) = {val spock = actor {	println("thinking ...")    }  }}
Actors that communicateAn actor is useless unless it cooperates with other actorsActors communicate via messagesIn Scala‘s actor library messages are processed in FIFO orderEvery actor owns an inbound and an outbound mailboxPage 54
Communicating Actors - ExamplePage 55!Note: react & receive have cousins with timeout arguments:   receiveWithin and reactWithinimport scala.actors._import Actor._object Calculator extends Actor {  def fib(n: Int) : Int = { require(n >= 0) // this is a precondition if (n <= 1) n else fib(n-2) + fib(n-1) }  def act() {loop {        react { // or receive if thread must preserve call-stack	       case i:Int => actor {println("Fibonacci of "+i+" is "+fib(i))}	       case s:String if (s == „exit")  => {println(„exit!"); exit}	       case _ => println("received unknown message")         }     }  }}object ActorDemo extends Application {   Calculator.start // start Actor   for (i <- 0 to 30) Calculator ! i // here we send a msg to the actorCalculator ! "exit"}

Oop2010 Scala Presentation Stal

  • 1.
    Introduction toCoding inScala is fun!OOP 2010Dr. Michael StalMichael.Stal@siemens.com
  • 2.
    Objectives of thisPresentationIntroduce core concepts of ScalaShowing you the benefits of combining OO with functional programmingIllustrating the language in a pragmatic way preferring code over theoryBut not to cover every available aspect or to cover aspects in full detailFor instance, we won‘t cover Java/Scala Interop, Views, Equality Semantics, Unit Testing, AnnotationsPage 2
  • 3.
    IntroductionScala created bythe team of Martin Odersky at EPFL„Scala“ means „Scalable Language“„Scalable“ means: the same language concepts for programming in the small & largeIn Scala this is achieved in a pragmatic way by combining Object Oriented Programming withFunctional Programming Scala is a statically typed language like JavaAll types are objectsPage 3Martin Odersky, Source: http://lamp.epfl.ch/~odersky/
  • 4.
    Object-Oriented & FunctionalProgrammingObject-Oriented ProgrammingAbstraction using Classes and InterfacesRefinement using subtyping and inheritance (Remember the Liskov Substitution Principle!)Dynamics through polymorphismFunctional ProgrammingHigher Order Functions as First-Class EntitiesADTs (Abstract Data Types) following algebraic conventionsPattern matchingParametric polymorphism (generic types)Page 4SCALA
  • 5.
    Core Properties ofScala (see Programming in Scala)Scala is compatible: runs on JVM, interoperability with JavaScala is concise: More compact code because removal of Java boilerplate code and powerful librariesScala is high-level: Higher level of abstraction by combining OO with functional programmingScala is statically typedPage 5Scala‘s Roots: Java, C#
  • 6.
  • 7.
  • 8.
  • 9.
    ErlangA smallAppetizer - Hello, Scala!Page 6Type InferenceImmutable valuesClassesclass HelloWorldClass (val name: String) { def print() = println("Hello World of " + name)}object HelloWorldMain { def main(args: Array[String]): Unit = {val hello = new HelloWorldClass("Scala") hello print }}=> Hello World of ScalaSingletonsLook Ma, no semicolonsNo brackets required!
  • 10.
    Stairway to Heaven– First Steps using Scala This source code file may be compiled using scalac und run using scala:scalac HelloWorldMain.scalascala HelloWorldMain Note: the source file must be named like the main object to be executed You may run an interpreter by using the following command line insteadscala HelloWorldMain.scala In this case you may also use plain Scala scripts (no classes or objects required)Or, even better, you might use an IDE like Idea, Netbeans, or EclipsePage 7
  • 11.
    A more advancedexample (1) (from Venkat Subramanian‘s book Programming Scala, pp.5)Page 8import scala.actors._import Actor._val symbols = List( "AAPL", "GOOG", "IBM", "JAVA", "MSFT")val receiver = selfval year = 2009symbols.foreach { symbol => actor { receiver ! getYearEndClosing(symbol, year) }}val (topStock, highestPrice) = getTopStock(symbols.length)printf("Top stock of %d is %s closing at price %f\n", year, topStock, highestPrice)def getYearEndClosing(symbol : String, year : Int) = { val url = new java.net.URL("http://ichart.finance.yahoo.com/table.csv?s=" + symbol + "&a=11&b=01&c=" + year + "&d=11&e=31&f=" + year + "&g=m") val data = io.Source.fromURL(url).mkString val price = data.split("\n")(1).split(",")(4).toDouble (symbol, price)} // .. to be continued
  • 12.
    A more advancedexample (2)(from Venkat Subramanian‘s book Programming Scala, pp.5)Run this within interpreter mode scala TopScala.scalaAfter the end of the talk return to this example and check whether you better understand itPage 9// continued ...def getTopStock(count : Int) : (String, Double) = { (1 to count).foldLeft("", 0.0) { (previousHigh, index) => receiveWithin(10000) { case (symbol : String, price : Double) => if (price > previousHigh._2) (symbol, price) else previousHigh } }} // will result in =>// Top stock of 2009 is GOOG closing at price 619,980000
  • 13.
    Scala Type HierarchyPage10Scala uses a pure object-oriented type systemEvery value is an objectTwo types: values and referencesAny is parent class of all classes, Nothing subclass of all classesBasictypes like inJavaSource: Scala Reference Manual
  • 14.
    First Class ScalaPage11born and id will bepublic fieldsMain constructorClasses in Scala contain fields, methods, types, constructorsVisibility is public per defaultclass CatID(val id : Int) //that's a whole classclass Cat(val born: Int, val id: CatID) {private var miceEaten: Int = 0 def digested() = miceEatendef hunt(miceCaught: Int) { miceEaten += miceCaught }}object ScalaClasses { def main(args: Array[String]) { val id = new CatID(42) val tom = new Cat(2010, id) tom.hunt(3) tom hunt 2 println(“cat was born in “ + tom.born) println(tom.digested) }} // => 5 <\n> Tom was born in 2010 definitionof methodsNo bracketsrequired
  • 15.
    Class ConstructorsPage 12classComplex (r : Double, i: Double) { println("Constructing a complex number") val re = r val im = i def this(r : Double) = this(r,0) override def toString = re + (if (im < 0) "-" + (-im) else "+" + im) + "*i" ...}Belongs toPrimaryconstructorAuxilliaryconstructorsmust callprimary
  • 16.
    Immutable and MutableObjectsScala provides immutable objects (functional programming) but also mutable objectsImmutability has many benefitsReduction of race conditions in concurrent programsProtection against unwanted modificationScala provides mutable & immutable versions of collection typesMutable objects are important to address objects that are supposed to change their state, but use them with carePage 13class Person(var name: String)object ImmutabilityDemo { def main(args:Array[String]) = {val s = "Michael" s = "Bill" // errorvar t = "Michael“ // t variable t = "Bill" // ok val c = new Person("Bill") c = new Person("Tom") // error// ok - c itself unchanged: c.name = "Tom" }}
  • 17.
    InheritanceIn Scala classescan be derived from at most one base classClasses may be abstractYou need to indicate whether you override inherited methodsPage 14abstractclass Shape {type Identifier = Int // defining types def getID() : Identifier = 42 def draw() : String // abstract method}class Circle (val cx: Double, val cy: Double, val r: Double) extends Shape { val id : Identifier = getID()override def draw() : String = "I am a Circle"}
  • 18.
    Companion Objects andStandalone ObjectsWe already saw standalone objectsObjects are singletonsIf you need static fields or methods for a class, introduce a companion class with the same nameConvention: apply() methods may be provided as factory methodsPage 15class Cat private (val born : Int, val id: CatID) { ...private def this(id: CatID) = this(2010, id) ...} // all constructors are privateobject Cat { // this is the companion object of Catdef apply(born: Int, id: CatID) = new Cat(born, id) def apply(id: CatID) = new Cat(id) // factory method def whatCatsDo() = "Sleep, eat, play" }object ScalaClasses { // Standalone Object def main(args: Array[String]) { val id = new CatID(43)val pussy = Cat(id) // no new required println("Pussy was born in " + pussy.born) println(Cat.whatCatsDo) // like static in Java }}
  • 19.
    Application Base ClassForexperimenting with Scala use the base class ApplicationJust compile this with: scalac ObjDemo.scalaAnd run it with: scala ObjDemoUseful abbreviation if you do not need to deal with command line argumentsPage 16 Inheritanceobject ObjDemoextends Application {val s: String = "Michael"println(s) // => Michael}
  • 20.
    TraitsClasses and instancesmay mix-in additional functionality using traitsTraits represent an abstraction between interfaces and classesUsing traits we can easily live with the single-inheritance restrictionYou may use also traits via anonymous classes: val x = new Identity{} x.name = "UFO" println(x.whoAmI)Page 17trait Identity { var name: String="" def whoAmI() : String = name }class Person extends Identity class Animalobject TraitDemo { def main(args:Array[String]) = { val p = new Person p.name = "Michael" println(p.whoAmI)val a = new Animal with Identity a.name = "Kittie" println(a.whoAmI) }} // => Michael <\n> Kittie
  • 21.
    Traits and VirtualSuper: Inheritance LinearizationPage 18abstract class Processor { def process() }trait Compressor extends Processor { // trait only applicable to Processor subclassabstract override def process() = { println("I am compressing"); super.process }}trait Encryptor extends Processor { // only applicable to Processor subclassabstract override def process() = { println("I am encrypting"); super.process}}class SampleProcessor extends Processor { // subclass of Processor override def process() = println("I am a Sample Processor")}object traitsample2 { def main(args:Array[String]) = { // mixing in a trait to an object:val proc1 = new SampleProcessor with Compressor with Encryptorproc1.process// Encryptor.process=>Compressor.process } // => SampleProcessor.process}Note: abstract override for a trait method means the actual subclass of Processor will provide a concrete implementation of that method!
  • 22.
    Scala Basics: ifStatementsIf statements are expressions themselves, i.e. they have valuesPage 19import java.util._if (1 + 1 == 3) println(“strange world”) else {println(“everything’s ok”)}val res = if ((new Random().nextInt(6) + 1) == 6) "You win!" else "You lose!"
  • 23.
    Scala Basics: forComprehensions (1)A for comprehension is like a for loop. It lets you traverse a collection, return every object in a temporary variable which is then passed to an expression. You may also specify nested iterations:You can specify filters for the collection elementsPage 20val aList = List(1,2,3,4,5,6)for (i <- aList) println(i) // => 1 <\n> 2 ...val dogs = Set("Lassie", "Lucy", "Rex", "Prince");for (a <- dogs if a.contains("L")) println(a)// => “Lassie” <\n> “Lucy”
  • 24.
    Scala Basics: forComprehensions (2)Yield allows to create new collections in a for comprehension:You can specify filters for the collection elementsPage 21var newSet = for { a <- dogs if a.startsWith("L") } yield aprintln(newSet) // Set(Lassie, Lucy)for { i <- List(1,2,3,4,5,6) j = i * 2 // new variable j defined} println(j) // => 2 <\n> 4 <\n> 6 ...
  • 25.
    Scala Basics: OtherloopsScala supports while and do-while loopsBut generator expressions such as (1 to 6) incl. 6 or (1 until 6) excl. 6 together with for make this much easierNote: The reason this works is a conversion to RichInt where to is defined as a method that returns an object of type Range.Inclusive, an inner class of Range implementing for comprehensionsPage 22var i = 1while (i <= 6) { println(i) i += 1} // = 1 <\n> 2 <\n> 3 ... for (i <- 1 to 6) println(i)
  • 26.
    Scala Basics: Exceptionhandlingtry-catch-finally available in Scala but throws isn‘tcatching checked exceptions is optional!catch-order important as in Java, C++ or C#Page 23def temperature(f: Double) { if (f < 0) throw new IllegalArgumentException()}try { println("acquiring resources") temperature(-5)}catch { case ex: IllegalArgumentException => println("temperatur < 0!") case _ => println("unexpected problem")}finally { println("releasing resources")}
  • 27.
    Inner ClassesYou maydefine inner classes as in JavaSpecial notation (<name> =>) for referring to outer class this from an inner class: you might also use <outerclass>.this insteadPage 24class Element (val id: String){ elem =>class Properties { // inner classtype KV = Tuple2[String, Any] var props: List[KV] = Nil def add(entry: KV) { props = entry :: props } override def toString = { var s: String = "" for (p <- properties.props) s = s + p +"\n" s }} override def toString = "ID = " + id + "\n" + properties val properties = new Properties }object InnerClassDemo extends Application { val e = new Element("Window") e.properties.add("Color", "Red") e.properties.add("Version", 42) println(e.toString)}
  • 28.
    Imports and PackagesWecan partition Scala definitions into packages:A package is a special object which defines a set of member classes, objects and packages. Unlike other objects, packages are not introduced by a definitionImporting packages works via import statements – almost like in JavaPackages scala, java.lang, scala.Predefare automatically importedPage 25package MyPackage1 { class Person(val name: String) class Animal(val name: String)}import MyPackage1._object PacDemo extends Application { val person = new Person("Michael") println(person name)} import p._ all members of p (this is analogous to import p.* in Java). import p.x the member x of p.
  • 29.
    import p.{x => a} the member x of p renamed as a.
  • 30.
    import p.{x, y} the members x and y of p.
  • 31.
    import p1.p2.z the member z of p2, itself member of p1.Advanced Types: ListsCollection Type: ListPage 26object ListDemo { def main(args:Array[String]) { val l1 : List[Int] = Nil // empty List val l2 = List[Int](1,2,3,4,5) // list with 5 elements val l3 = 0 :: l2 // add 0 to the list val l4 = List[Int](0,1,2) ::: List[Int](3,4,5) // concat 2 lists println("Top Element: " + l4.head) // => 0 println("Rest of list: " + l4.tail) // => List(1,2,3,4,5) println("Last Element: " + l4.last) // => 5l4.foreach { i => println(i) } // => 1 <\n> 2 <\n> 3 ... }}Foreach traverses a list and passes each element found to the closure passed as argument
  • 32.
    Advanced Types: SetsCollectionType: SetPage 27object SetDemo { def main(args:Array[String]) {val s1 = Set[Int](1,2,3,4,5) // we could also use = Set(1,2,3,4,5)val s2 = Set[Int](2,3,5,7)println(s2.contains(3)) // => trueval s3 = s1 ++ s2 // unionprintln(s3) // => Set(5,7,3,1,4,2)vals4 = s1 & s2 // intersection: in earlier versions **println(s4) // Set(5,3,2) }}
  • 33.
    Advanced Types: MapsCollectionType: MapPage 28object MapDemo { def main(args:Array[String]) {val m1 = Map[Int, String](1 -> "Scala", 2->"Java", 3->"Clojure")valm2 = m1 + (4 -> "C#") // add entryprintln(m2 + " has size " + m2.size) //=> Map(1->Scala,…) has size 4println(m1(1)) // => Scalaval m3 = m2 filter { element => val (key, value) = element (value contains "a") } println(m3) // => Map(1->Scala, w->Java) }}
  • 34.
    Advanced Types: OptionsobjectDayOfWeek extends Enumeration { val Monday = Value("Monday") //argument optional val Sunday = Value("Sunday") //argument optional }import DayOfWeek._ object OptionDemo { def whatIDo(day: DayOfWeek.Value) : Option[String] = { day match { case Monday => Some("Working hard") case Sunday => None } } def main(args:Array[String]) { println(whatIDo(DayOfWeek.Monday)) println(whatIDo(DayOfWeek.Sunday)) } //=> Some(„Working Hard“) <\n> None}The Option type helps dealing with optional valuesFor instance, a search operation might return a result or nothingWe are also introducing EnumerationtypesPage 29
  • 35.
    Advanced Types: RegularExpressionsType: Regex introduces well-known regular expressionsPage 30With this syntax strings remain formatted as specified and escape sequences are not requiredobject RegDemo { def main(args:Array[String]) {val pattern = """\d\d\.\d\d\.\d\d\d\d""".rval sentence = “X was born on 01.01.2000 ?"println (pattern findFirstIn sentence) // => Some(01.01.2000) }}Note: the „r“ in “““<string>“““.r means: regular expression
  • 36.
    Advanced Types: TuplesTuplescombine fixed number of Elements of various typesThus, you are freed from creating heavy-weight classes for simple aggregatesPage 31println( (1, "Douglas Adams", true) )def goodBook = {("Douglas Adams", 42, "Hitchhiker's Guide")} println ( goodBook._3 ) // get third element// => (1, Douglas Adams, true)// => Hitchhiker‘s Guide
  • 37.
    Advanced Types: ArraysArrayshold sequences of elementsAccess very efficientPage 32val a1 = new Array[Int](5) // initialized with zeros val a2 = Array(1,2,3,4,5) // initialized with 1,2,3,4,5println( a2(1) ) // => 2a2(1) = 1 // => Array (1,1,3,4,5)Note:In Scala the assignment operator = does not return a reference to the left variable (e.g., in a = b).Thus, the following is allowed in Java but not in Scala: a = b = c
  • 38.
    Smooth OperatorIn Scalaoperator symbols are just plain method names For instance 1 + 2 stands for 1.+(2)Precedence rules:All letters|^&< >= !:+ -* / %Page 33class Complex(val re:Double, val im:Double) {def +(that: Complex) : Complex = { new Complex(this.re + that.re, this.im + that.im) } override def toString() : String = { re + (if (im < 0) "" else "+") + im +"i" }}object Operators { def main(args: Array[String]) { val c1 = new Complex(1.0, 1.0) val c2 = new Complex(2.0, 1.0) println(c1+c2) }} // => (3.0+2.0i)
  • 39.
    ConversionsImplicit converters allowScala to automatically convert data typesSuppose, you‘d like to introduce a mathematical notatation such as 10! Using implicit type converters you can easily achieve thisPage 34object Factorial { def fac(n: Int): BigInt = if (n == 0) 1 else fac(n-1) * n class Factorizer(n: Int) {def ! = fac(n) }implicit def int2fac(n: Int) = new Factorizer(n)}import Factorial._object ConvDemo extends Application {println("8! = " + (8!)) // 8 will be implicitly converted} // => 40320
  • 40.
    Parameterized Types inScalaClasses, Traits, Functions may be parameterized with typesIn contrast to Java no wildcards permitted – parameter types must have namesVariance specification allow to specify covariance and contravariancePage 35trait MyTrait[S,T] { def print(s:S, t:T) : String = "(" + s + "," + t + ")"}class MyPair[S,T] (val s : S, val t : T) extends MyTrait [S,T] { override def toString() : String = print(s,t) }object Generics { def main(args: Array[String]) { val m = new MyPair[Int,Int](1,1) printf(m.toString()) }} // => (1,1)
  • 41.
    Small Detour toVariance and Covariance / Type BoundsIf X[T] is a parameterized type and T an immutable type:X[T] is covariant in T if: S subTypeOf T => X[S] subTypeOf X[T]X[T] is contravariant in T if: S subTypeOf T => X[S] superTypeOf X[T]In Scala covariance is expressed as X[+T] and contravariance with X[-T]Covariance is not always what you want: Intuitively we could assign a set of apples to a set of fruits. However, to a set of fruits we can add an orange. The original set of apples gets „corrupted“ this wayExample List[+T]: Covariance means a List[Int] can be assigned to a List[Any] because Int is subtype of AnyUpper/Lower Bounds may be specified:In the following example D must be supertype of S: def copy[S, D>:S](src: Array[S], dst: Array[D]) = { ...Page 36
  • 42.
    Functional Aspects: Functionsand ClosuresIn Scala Functions are First-Class CitizensThey can be passed as argumentsassigned to variables: val closure={i:Int => i+42}Nested functions are also supportedPage 37object scalafunctions { def add(left:Int,right:Int, code:Int=>Int)= {var res = 0 for (i<-left to right) res += code(i) res } def main(args: Array[String]) {println(add(0,10, i => i))println(add(10,20, i => i % 2 )) }}=>555
  • 43.
    Functional Aspects: Call-by-NameIfa parameterless closure is passed as an argument to a function, Scala will evaluate the argument when the argument is actually usedThis is in contrast to call-by-value argumentsA similar effect can be achieved using lazy (value) evaluation: lazy val = <expr> Page 38import java.util._object CbNDemo {def fun(v: => Int) : Int = v // v is a Call-by-Name Parameterdef v() : Int = new Random().nextInt(1000) def main(args:Array[String]) { println( fun(v) ) println( fun(v) ) }} // => 123 <\n> 243
  • 44.
    Functional Aspects: Currying(1)Currying means to transform a function with multiple arguments to a nested call of functions with one (or more) argument(s)def fun(i:Int)(j:Int) {} (Int)=>(Int)=>Unit=<function1>Page 39object scalafunctions { def fun1(i:Int, j:Int) : Int = i + jdef fun2(i:Int)(j:Int) : Int = i + j def main(args: Array[String]) { println(fun1(2,3)) println(fun2(2){3}) println(fun2{2}{3} ) }} // => 5 5 5
  • 45.
    Functional Aspects: Currying(2)Currying helps increase readabilityTake foldleft as an examplePage 40FoldLeft Operatorval x = (0 /: (1 to 10)) { (sum, elem) => sum + elem } // 55 Carryover value for next iterationFunction argumentsCarryover valueCollectionFor each iteration, foldleft passes the carry over value and the current collection element. We need to provide the operation to be appliedThis is collection which we iterate overThis is the value that is updated in each iterationThink how this would be implemented in Java!
  • 46.
    Positional ParametersIf youuse a parameter only once, you can use positional notation of parameters with _ (underscore) insteadPage 41object scalafunctions { def main(args:Array[String]) { val seq= (1 to 10) println( (0 /: seq) { (sum, elem) => sum + elem } ) println( (0 /: seq) { _ + _ } ) } }
  • 47.
    Using the featureswe can build new DSLs and additional features easilyThe following loop-unless example is from the Scala tutorial Page 42object TargetTest2 extends Application {def loop(body: => Unit): LoopUnlessCond = new LoopUnlessCond(body)protected class LoopUnlessCond(body: => Unit) { def unless(cond: => Boolean) { body if (!cond) unless(cond) } } var i = 10 loop { println("i = " + i) i -= 1 } unless (i == 0)}We are calling loopwith this body ...and invoking unlesson the result
  • 48.
    Functional Aspect: PartiallyApplied FunctionsIf you only provide a subset of arguments to a function call, you actually retrieve a partially defined functionOnly the passed arguments are bound, all others are notIn a call to a partially applied function you need to pass the unbound argumentsAll this is useful to leverage the DRY principle when passing the same arguments again and againPage 43object scalafunctions { def fun(a : Int, b : Int, c:Int) = a+b+c def main(args: Array[String]) {val partialFun = fun(1,2,_:Int) println( partialFun(3) ) // 6 println( partialFun(4) ) // 7 }}
  • 49.
    Functions Are ObjectsFunction: S => T trait Function1[-S,+T] { def apply(x:S):T }Example: (x: Int) => x * 2-> new Function1[Int,Int] { def apply(X:Int):Int = x * 2 }In Scala all function values are objectsBasically, each function is identical to a class with an apply methodThus, you can even derive subclasses from functionsArray is an example for this: class Array [T] (length: Int ) extends (Int => T) {def length: Int = ...Page 44
  • 50.
    Functional Aspects: PatternMatchingPattern matching allows to make a pragmatic choice between various optionsPage 45valaNumber = new Random().nextInt(6) + 1;aNumbermatch {case 6 => println("You got a 6")case 1 => println("You got a 1");caseotherNumber => println("It is a " + otherNumber)}
  • 51.
    Functional Aspects: Matchingon TypesIt is also possible to differentiate by type:Page 46object TypeCase { def matcher(a: Any) {a match { case i : Int if (i == 42) => println("42") case j : Int => println("Another int") case s : String => println(s) case _ => println("Something else") } } def main(args: Array[String]) { matcher(42) matcher(1) matcher("OOP") matcher(1.3) }} // => 41 <\n> 1 <\n> OOP <\n> Something else
  • 52.
    Functional Aspects: Matchingon ListsLists can be easily used with Pattern Matching:Page 47object ListCase { def matcher(l: List[Int]) {l match { case List(1,2,3,5,7) => println("Primes") case List(_,_,_3,_) => println("3 on 3"); case 1::rest => println("List with starting 1"); case List(_*) => println("Other List"); } } def main(args: Array[String]) { matcher(List(1,2,3,5,7)) matcher(List(5,4,3,2)) matcher(List(1,4,5,6,7,8)); matcher(List(42)) }} => Primes <\n> 3 on 3 <\n> List with starting 1 <\n> Other List
  • 53.
    Functional Aspects: Matchingon TuplesSo do Tuples:Page 48object TupleCase { def matcher(t : Tuple2[String,String]) {t match { case ("OOP",s) => println("OOP " + s) case ("Scala", s) => println("Scala " + s) case _ => println("Other Tuple") } } def main(args: Array[String]) { matcher("OOP", "2010") matcher("Scala", "rocks"); matcher("A","B") }} => OOP 2010 <\n> Scala rocks >cr> Other Tuple
  • 54.
    Functional Aspects: Matchingon Case ClassesCase Classes are classes for which the compiler generates additional functionality to enable pattern matching, e.g., an apply() method:Page 49sealed abstract class Shape // sealed => subclasses only in this source filecase class Circle(val center: Point, val radius: Double) extends Shapecase class Line(val pt1: Point, val pt2: Point) extends Shapecase class Point (val x:Double, val y:Double){ override def toString() = "(" + x +"," + y + ")" }object CaseClasses { def matcher(s : Shape) {s match { case Circle(c, r) => println(“Circle“ : + c + “ “ + r) case Line(p1, p2) => println("Line " + p1 + " : " + p2) case _ => println("Unknown shape") } } def main(args: Array[String]) { matcher(Circle(Point(1.0, 1.0), 2.0)) matcher(Line(Point(1.0, 1.0), Point(2.0, 2.0))) }}
  • 55.
    Functional Aspect: ExtractorsExtractorsare objects with an unapply method used to match a value and partition it into constituents – an optional apply is used for synthesisPage 50object EMail { def apply(prefix: String, domain: String) = prefix + "@" + domaindef unapply(s: String): Option[(String,String)] = { val parts = s split "@" if (parts.length == 2) Some(parts(0), parts(1)) else None } }object scalafunctions { def main(args:Array[String]) { val s = "michael.stal@siemens.com" s match { case EMail(user, domain) => println(user + " AT " + domain) case _ => println("Invalid e-mail") } } }
  • 56.
    Partial Functions PartialFunctions are not defined for all domain valuesCan be asked with isDefinedAt whether a domain value is acceptedExample: Blocks of Pattern Matching CasesPage 51trait PartialFunction[-D, +T] extends (D => T) { def isDefinedAt(x: D): Boolean}
  • 57.
    ActorsActors have beenintroduced in the 1970s:the Actor model is a mathematical model of concurrent computationthat treats "actors" as the universal primitives of concurrent digital computation: in response to a message that it receives, an actor can make local decisions, create more actors, send more messages, and determine how to respond to the next message received. [Hewitt, 73]Page 52Also available in Erlang, Axum, Io, ClojureProvided as library implementation in Scala (demonstrating Scala‘s capability of providing internal DSLs)
  • 58.
    Actor ClassesClass Actorrequires to override act() which is the functionality executed by a threadYou may also instantiate anonymous actors in a much more convenient way:Page 53import scala.actors.Actorclass VolcanextendsActor {def act() {println(“thinking ...") }}object SpockRunner { def main(args:Array[String]) = {valspock = new Volcanspock start }}import scala.actors.Actorimport Actor._object SpockRunner { def main(args:Array[String]) = {val spock = actor { println("thinking ...") } }}
  • 59.
    Actors that communicateAnactor is useless unless it cooperates with other actorsActors communicate via messagesIn Scala‘s actor library messages are processed in FIFO orderEvery actor owns an inbound and an outbound mailboxPage 54
  • 60.
    Communicating Actors -ExamplePage 55!Note: react & receive have cousins with timeout arguments: receiveWithin and reactWithinimport scala.actors._import Actor._object Calculator extends Actor { def fib(n: Int) : Int = { require(n >= 0) // this is a precondition if (n <= 1) n else fib(n-2) + fib(n-1) } def act() {loop { react { // or receive if thread must preserve call-stack case i:Int => actor {println("Fibonacci of "+i+" is "+fib(i))} case s:String if (s == „exit") => {println(„exit!"); exit} case _ => println("received unknown message") } } }}object ActorDemo extends Application { Calculator.start // start Actor for (i <- 0 to 30) Calculator ! i // here we send a msg to the actorCalculator ! "exit"}
  • 61.
    Processing XML inScalaScala can directly handle XMLWith package scala.xml we can read, parse, create and store XML documentsXPath like query syntaxPage 56import scala.xml._ // in our example not requiredobject XMLDemo extends Application { val x : scala.xml.Elem = <conferences> <conference name="OOP"> <year> 2010 </year> </conference> <conference name="SET"> <year> 2010 </year> </conference> </conferences> var conferenceNodes = x \ "conference„ // get all conference nodes for (c <- conferenceNodes) println( c\"@name“ ) // get attribute} // => OOP <\n> SET
  • 62.
    Accessing the Webwith ScalaYou may use a mixture of Java and Scala code to access the WebSuppose, you‘d like to read a Web PageHere is an example how this might workPage 57import java.net._object WebDemo { def main(args: Array[String]) { require(args.length == 1)// we assume an URL was passed at the // command line:val url = new URL(args(0)) // make URL// read web page stream and convert // result to a string: val page = io.Source.fromURL(url).mkString println(page) // display result }}
  • 63.
    Scala Installation &UseDownload distribution from http://www.scala-lang.orgYou may useScala Compilers: scalac and fscEclipse, JetBrains, NetBeans Plug-InREPL (Read-Eval-Print-Loop) shell: scalaI have tested these on Windows {XP, Vista} as well as Mac OS X (Snow Leopard)Or a Web site for evaluating Scala scripts: http://www.simplyscala.com/If you are interested in a Web Framework based on Scala use Lift 1.0: http://liftweb.net/Page 58
  • 64.
    SummaryScala combines thebest of two worlds: OO and Functional ProgrammingIt runs on the JVM and offers Java interoperabilityActor library helps dealing with complexity of concurrent programming Scala programs are compact and concise => big productivity boost possibleUpcoming v2.8 will offer additional benefits such as named & default argumentsScala is no island - many further tools and frameworks (e.g., Lift) availableCoding with Scala is fun - Try it yourself!Page 59
  • 65.
    Books: My RecommendationsM.Odersky, L. Spoon, B. Venners: Programming in Scala: A Comprehensive Step-by-step Guide (Paperback), Artima Inc; 1st edition (November 26, 2008) – The Language Reference!V. Subramanian: Programming Scala: Tackle Multi-Core Complexity on the Java Virtual Machine (Pragmatic Programmers) (Paperback), Pragmatic Bookshelf (July 15, 2009) D. Wempler, A. Paine: Programming Scala: Scalability = Functional Programming + Objects (Animal Guide) (Paperback), O'Reilly Media; 1st edition (September 25, 2009)A lot of additional books available in the meantime. Page 60