SlideShare ist ein Scribd-Unternehmen logo
1 von 81
Functions rock!Harnessing the Power of Functional Part I: Programming with Scala TUTORIAL QCON 2011, London Prof. Dr. Michael Stal Michael.Stal@siemens.com
Objectives of Presentation Introducing core concepts of Functional Programming Introducing Scala as example Presentingthe benefits of combining OO and functional programming Illustrating the language in a pragmatic way preferring code over theory But not to cover every available aspect or to cover aspects in full  detail Page 2
Whatis Functional Programming? Praise the Lambda Calculus (which is almost 80 years old) and its successors  (e.g., the typed ones) (Mathematical) Functions Are a means of decomposition Can be assigned to variables  Can be passed as arguments to or returned from functions  Can be anonymous (closures) Emphasize on Immutability:  No side-effects of functions (referential transparency) Values instead of variables   Page 3
Functional ProgrammingLanguages … Are oftenhybrid such as Lisp/Clojure, F#, Scala Use Recursion instead of Iteration Can be strict (eager) or non-strict (lazy) Use  mainly the Typed Lambda Calculus and thus support Pattern Matching Support concepts such as Monads, Continuations Integrate Comprehensions for collection types, Catamorphisms (fold), Anamorphisms (unfold) Page 4
Preconception: Functional LanguagesareSlow Isnottrueanymoredue to: HighlyefficientVMslikethe CLR, JVM StructuralSharing, no naive copying TailCallOptimization: at least someVMs Veryefficient and powerfulLibraries Easy leveraging of Concurrency (e.g., because of immutablity) Page 5
Object-Oriented & Functional Programming Object-Oriented Programming Abstraction using Classes and Interfaces Refinement using subtyping and inheritance (Remember the Liskov Substitution Principle!) Dynamics through polymorphism Functional Programming Higher Order Functions as First-Class Entities ADTs (Abstract Data Types) following algebraic conventions Pattern matching Parametric polymorphism (generic types) Page 6 SCALA
Introduction to Scala 2.8.x Scala created by the team of Martin Odersky at EPFL „Scala“ means „Scalable Language“ „Scalable“ means:  the same language concepts for programming in the small & large In Scala this is achieved in a pragmatic way by combining  Object Oriented Programming with Functional Programming  Scala is a statically typed language like Java All types are objects Page 7 Martin Odersky, Source: http://lamp.epfl.ch/~odersky/
Core Properties of Scala (seeBookProgramming in Scala) Scala is compatible: runs on JVM, interoperability with Java Scala is concise: More compact code because removal of Java boilerplate code and powerful libraries Scala is high-level: Higher level of abstraction by combining OO with functional programming Scala is statically typed Page 8 Scala‘s Roots: ,[object Object]
 Smalltalk, Ruby
 Beta, Simula, Algol
 ML
 Erlang,[object Object]
Stairway to Heaven – First Steps using Scala  This source code file may be compiled using scalac und run using scala: scalac HelloWorldMain.scala scala 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 instead scala 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 Eclipse Page 10
Scala Type Hierarchy Page 11 Scala uses a pure object-oriented type system Every value is an object Two types: values and references Any is parent class of all classes, Nothing subclass of all classes Basic types like in Java Source: Scala Reference Manual
First Class Scala Page 12 born and  id will be public fields Main constructor Classes in Scala contain fields, methods, types, constructors Visibility is public per default class CatID(val id : Int)  //that's a whole class class Cat(val born: Int, val id: CatID) { private var miceEaten: Int = 0    def digested() = miceEaten def 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 <> Tom was born in 2010  definition of methods No brackets required
Class Constructors Page 13 class 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 to Primary constructor Auxilliary constructorsmust call primary
Immutable and Mutable Objects Scala provides immutable objects (functional programming) but also mutable objects Immutability has many benefits Reduction of race conditions in concurrent programs Protection against unwanted modification Scala provides mutable & immutable versions of collection types Mutable objects are important to address objects that are supposed to change their state, but use them with care Page 14 class Person(var name: String) object ImmutabilityDemo {  def main(args:Array[String]) = { val s = "Michael"    s = "Bill" // error var t = "Michael“ // t variable    t = "Bill" // ok    val c = new Person("Bill")    c = new Person("Tom") // error // ok - c itself unchanged:    c.name = "Tom"  } }
Inheritance In Scala classes can be derived from at most one base class Classes may be abstract You need to indicate whether you override inherited methods Page 15 abstractclass 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 Objects We already saw standalone objects Objects are singletons If you need static fields or methods for a class, introduce a companion class with the same name Convention: apply() methods may be provided as factory methods Page 16 class Cat private (val born : Int, val id: CatID) {    ... private def this(id: CatID) = this(2010, id)    ... } // all constructors are private object Cat { // this is the companion object of Cat def 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 Class For experimenting with Scala use the base class Application Just compile this with: scalac ObjDemo.scala And run it with: scala ObjDemo Useful abbreviation if you do not need to deal with command line arguments Page 17   Inheritance object ObjDemoextends Application { val s: String = "Michael" println(s) // => Michael }
Traits Classes and instances may mix-in additional functionality using traits Traits represent an abstraction between interfaces and classes Using traits we can easily live with the single-inheritance restriction You may use also traits via anonymous classes: 	val x = new Identity{}   	x.name = "UFO"   	println(x.whoAmI) Page 18 trait   Identity  {    var name: String=""    def whoAmI() : String = name	 } class  Person(var name: String)          extends Identity  class Animal object 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 <> Kittie
Traits and Virtual Super: Inheritance Linearization Page 19 abstract class Processor { def process() } trait Compressor extends Processor { // trait only applicable to Processor subclass abstract override def process() =  { println("I am compressing"); super.process } } trait Encryptor extends Processor { // only applicable to Processor subclass abstract 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 Encryptor proc1.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 Statements If statements are expressions themselves, i.e. they have values Page 20 import 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 elements Page 21 val aList  = List(1,2,3,4,5,6) for (i <- aList) println(i) // => 1 <> 2 ... val dogs = Set("Lassie", "Lucy", "Rex", "Prince"); for (a <- dogs if a.contains("L")) println(a) // => “Lassie” <> “Lucy”
Scala Basics: for Comprehensions (2) Yield allows to create new collections in a for comprehension: You can specify filters for the collection elements Page 22 var newSet = for {                    a <- dogs                    if a.startsWith("L")              } yield a println(newSet)  // Set(Lassie, Lucy) for {      i <- List(1,2,3,4,5,6)     j = i * 2 // new variable j defined } println(j) // => 2 <> 4 <> 6 ...
Scala Basics: Other loops Scala supports while and do-while loops But generator expressions such as (1 to 6)  incl. 6 or (1 until 6) excl. 6 together with for make this much easier Note: 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 comprehensions Page 23 var i = 1 while (i <= 6)  {     println(i)     i  += 1 } // = 1 <> 2 <> 3 ...  for (i <- 1 to 6) println(i)
Scala Basics: Exception handling try-catch-finally available in Scala but throws isn‘t catching checked exceptions is optional! catch-order important as in Java, C++ or C# Page 24 def 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 Classes You may define inner classes as in Java Special notation (<name> =>)  for referring to outer class this from an inner class: you might also use <outerclass>.this instead Page 25 class Element (val id: String){ elem => class Properties { // inner class type 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 +""       s     } }   override def toString = "ID = " + id + "" + 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 Packages We 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 definition Importing packages works via import statements – almost like in Java Packages scala, java.lang, scala.Predefare automatically imported Page 26 package 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) } ,[object Object],                                  to import p.* in Java).  ,[object Object]
 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.,[object Object]
Advanced Types: Sets Collection Type: Set Page 28 object 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))  // => true val s3 = s1 ++ s2 // union println(s3) // => Set(5,7,3,1,4,2) vals4 = s1 & s2 // intersection: in earlier versions ** println(s4) // Set(5,3,2)   } }
Advanced Types: Maps Collection Type: Map Page 29 object MapDemo {  def main(args:Array[String]) { val m1 = Map[Int, String](1 -> "Scala", 2->"Java", 3->"Clojure") valm2 = m1 + (4 -> "C#") // add entry println(m2 + " has size " + m2.size)                             //=> Map(1->Scala,…) has size 4 println(m1(1)) // => Scala val m3 = m2 filter { element => val (key, value) = element                     (value contains "a") }   println(m3) // => Map(1->Scala, w->Java)  } }
Advanced Types: Options object 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“) <> None } The Option type helps dealing with optional values For instance, a search operation might return  a result or nothing We are also introducing Enumerationtypes Page 30
Advanced Types: Regular Expressions Type: Regex introduces well-known regular expressions Page 31 With this syntax strings remain formatted as specified and escape sequences are not required object RegDemo {  def main(args:Array[String]) { val pattern = """""".r val 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: Tuples Tuples combine fixed number of Elements of various types Thus, you are freed from creating heavy-weight classes for  simple aggregates Page 32 println( (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: Arrays Arrays hold sequences of elements Access very efficient Page 33 val a1 = new Array[Int](5) // initialized with zeros  val a2 = Array(1,2,3,4,5) // initialized with 1,2,3,4,5 println( a2(1) ) // => 2 a2(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 Operator In Scala operator symbols are just plain method names  For instance 1 + 2 stands for 1.+(2) Precedence rules: All letters | ^ & <  > =  ! : +  - *  /  % Page 34 class 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)
Conversions Implicit converters allow Scala to automatically convert data types Suppose, you‘d like to introduce a mathematical notatation such as 10!  Using implicit type converters you can easily achieve this Page 35 object 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 Scala Classes, Traits, Functions may be parameterized with types In contrast to Java no wildcards permitted – parameter types must have names Variance specification allow to specify covariance and contravariance Page 36 trait 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 Bounds If 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 way Example List[+T]: Covariance means a List[Int] can be assigned to a List[Any] because Int is subtype of Any Upper/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 37
Functional Aspects: Functions and Closures In Scala Functions are First-Class Citizens They can be  passed as arguments assigned to variables:           val closure={i:Int => i+42} Nested functions are also supported Page 38 object 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  ))   } } => 55 5
Functional Aspects: Call-by-Name If a parameterless closure is passed as an argument to a function, Scala will evaluate the argument when the argument is actually used This is in contrast to call-by-value arguments A similar effect can be achieved using lazy (value) evaluation:      lazy val = <expr>        Page 39 import java.util._ object CbNDemo { def fun(v: => Int) : Int = v   // v is a Call-by-Name Parameter def v() : Int = new Random().nextInt(1000)  def main(args:Array[String]) {    println( fun(v) )    println( fun(v) )    } } // => 123 <> 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 40 object scalafunctions {    def fun1(i:Int, j:Int) : Int = i + j def 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 readability Take foldleft as an example Page 41 FoldLeft Operator val x =  (0 /: (1 to 10)) { (sum, elem) => sum + elem } // 55  Carryover value for next iteration Function arguments Carryover value Collection For each iteration, foldleft passes the carry over value and the current collection element. We need to provide the operation to be applied This is collection which we iterate over This is the value that is updated in each iteration Think how this would be implemented in Java!
Positional Parameters If you use a parameter only once, you can use positional notation of parameters with _ (underscore) instead Page 42 object 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 easily The following loop-unless example is from the Scala tutorial  Page 43 object 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 loop with this body ... and invoking unless on the result
Functional Aspect: Partially Applied Functions If you only provide a subset of arguments to a function call, you actually retrieve a partially defined function Only the passed arguments are bound, all others are not In a call to a partially applied function you need to pass the unbound arguments All this is useful to leverage the DRY principle when passing the same arguments again and again Page 44 object 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 objects Basically, each function is identical to a class with an apply method Thus, you can even derive subclasses from functions Array is an example for this:  class Array [T] (length: Int )  extends (Int => T)  { def length: Int = ... Page 45
Functional Aspects: Pattern Matching Pattern matching allows to make a  pragmatic choice between various options Page 46 valaNumber = 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 Types It is also possible to differentiate by type: Page 47 object 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 <> 1  <> OOP <> Something else
Functional Aspects: Matching on Lists Lists can be easily used with Pattern Matching: Page 48 object 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 <> 3 on 3 <> List with starting 1 <> Other List
Functional Aspects: Matching on Tuples So do Tuples: Page 49 object TupleCase {    def matcher(t : Tuple2[String,String]) { t match { case („QCON",s) => println(„QCON " + s)   		case ("Scala", s) => println("Scala " + s) 	   	case _ => println("Other Tuple")         }    }    def main(args: Array[String]) { matcher(„QCON", "2011") 	matcher("Scala", "rocks"); 	matcher("A","B")    } } => QCON 2011 <> Scala rocks >cr> Other Tuple
Functional Aspects: Matching on Case Classes Case Classes are immutable classes for which the compiler generates additional functionality to enable pattern matching, e.g., an apply() method: Page 50 sealed abstract class Shape // sealed => subclasses only in this source file case class Circle(val center: Point, val radius: Double) extends Shape case class Line(val pt1: Point, val pt2: Point) extends Shape case 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)))    } } There are also case objects  !!!
Functional Aspect: Extractors Extractors are objects with an unapply method used to match a value and partition it into constituents – an optional apply is used for synthesis Page 51 object EMail {   def apply(prefix: String, domain: String) = prefix + "@" + domain def 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 values Can be asked with isDefinedAt whether a domain value is accepted Example: Blocks of Pattern Matching Cases Page 52 trait PartialFunction[-D, +T]  extends (D => T) {   def isDefinedAt(x: D): Boolean }
Actors by Example Page 53 ! Note: react & receive have cousins with timeout arguments:   receiveWithin and reactWithin import 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 actor Calculator ! "exit" }
Processing XML in Scala Scala can directly handle XML With package scala.xml we can read, parse, create and store XML documents XPath like query syntax Page 54 import scala.xml._ // in our example not required object XMLDemo extends Application {    val x : scala.xml.Elem =  <conferences>      <conference name=„QCON"> <year> 2011 </year> </conference>      <conference name=„GOTO"> <year> 2011 </year> </conference>    </conferences>    var conferenceNodes = x "conference„ // get all conference nodes    for (c <- conferenceNodes) println( cquot;@name“ ) // get attribute } // => 	OOP <> SET
Accessing the Web with Scala You may use a mixture of Java and Scala code to access the Web Suppose, you‘d like to read a Web Page Here is an example how this might work Page 55 import 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      } }
Combinator Parsing Scala allows to implement DSL parsers (LL(1)) For basic elements such as symbols, floats, strings etc. lexers are provided Developers can provide their own  Let us use a simple example: a language that defines polygons as lists of points such as [(-1,0)(0,1)(+1,0)]  which represents a triangle The grammar is pretty simple: poly	::= coord * coord	::= “(“ number “,“ number “)“  number aka floatingPointNumber is predefined Page 56
Build the Parser in Scala -  Part I Page 57 import scala.util.parsing.combinator._ class PolygonParserClass1 extends JavaTokenParsers {   def poly  : Parser[Any] = "["~rep(point)~"]"   def point : Parser[Any] =  "("~floatingPointNumber~","~floatingPointNumber~")" } object PolygonParser1 extends PolygonParserClass1 {   def parse (input: String) = parseAll(poly, input) } object ParserDemo extends Application { println(PolygonParser1.parse("[(1,2)(3,7)]")) } => parsed: (([~List((((((~1)~,)~2)~)), (((((~3)~,)~7)~))))~]) ~ 	: sequence		~>	: ignore left side of production rep( )	: repetition		<~	: ignore right side of production opt()	: option |	; alternative
Build the Parser in Scala -  Part 2 Page 58 Now, we would like to produce some code instead of just syntax checking We can add actions using ^^ case class Point(x : Float, y : Float) class PolygonParserClass2 extends JavaTokenParsers {   def poly : Parser[List[Point]] = "["~>rep(coor)<~"]" ^^                                        { List[Point]() ++ _ }    def coor : Parser[Point] =         "("~floatingPointNumber~","~floatingPointNumber~")" ^^         { case "("~x~","~y~")"  => Point(x.toFloat,y.toFloat) } } object PolygonParser2 extends PolygonParserClass2 {   def parse (input: String) = parseAll(poly, input) }  object ParserDemo extends Application {   println(PolygonParser2.parse("[(1,2)(3,7)]")) } => parsed: List(Point(1.0,2.0), Point(3.0,7.0))
New in Version 2.8: Packrat Parsers Page 59 With Packrat parsers you can handle left recursion In addition parsing is possible in constant time but unlimited lookahead import scala.util.parsing.combinator._ import scala.util.parsing.input.CharArrayReader case class Point(x : Float, y : Float) object PackratParserDemo extends JavaTokenParsers with PackratParsers {   lazy val poly : Parser[List[Point]] = "["~>rep(coor)<~"]" ^^          { List[Point]() ++ _ }    lazy val coor : Parser[Point] =              "("~floatingPointNumber~","~floatingPointNumber~")" ^^          { case "("~x~","~y~")"  => Point(x.toFloat,y.toFloat) } } object ParserDemo extends Application {   println(PackratParserDemo.phrase(PackratParserDemo.poly)        (new CharArrayReader("[(1,2)(4,5)]".toCharArray))) }=> parsed: List(Point(1.0,2.0), Point(4.0,5.0))
What is new in Scala 2.8.x So far we covered basically Scala 2.7 In the meantime, the new Scala version 2.8 is available with some improvements, e.g.: collection library has been reorganized and optimized tools improvements such as for REPL performance improvements For details around Scala 2.8 refer to http://www.scala-lang.org/node/198 Let me provide main changes of Scala version 2.8 in a Nutshell see also Dean Wampler‘s blog: http://blog.objectmentor.com/articles/2009/06/05/bay-area-scala-enthusiasts-base-meeting-whats-new-in-scala-2-8 Page 60
Scala 2.8 in a Nutshell - Default arguments Default arguments get a default value Page 61 object O {   def charge(amount: Double, Currency : String = “GBP"){     // do whatever necessary to get the money println(amount + " " + Currency) } def main(args : Array[String]) : Unit = { 	  charge (200.0) 	  charge (120.67, "EUR")   } }
Scala 2.8 in a Nutshell - Named arguments Named arguments help to call methods without being constrained by order of arguments  Page 62 object O { def welcome(firstName: String, lastName : String){ println("Hello " + firstName + " " + lastName)   } def main(args : Array[String]) : Unit = { welcome(lastName= “Duck“, firstName = “Donald")   } }
Scala 2.8 in a Nutshell - Annotations Annotations can be nested: @specialized annotation: Scala generics are fully specified at declaration place with a uniform implementation. This reduced performance for „primitive“ types (i.e., those derived from AnyVal). The annotation forces the compiler to generate an optimized version of the Generic for such types: Page 63 @ExcellentClass(arg= @AuthorDetails) def m[@specialized T](x: T, f: T => T) = f(x) m(2, (x:Int) => x * 2)
Scala 2.8 in a Nutshell  -  Continuations Continuations are the most difficult to understand feature ( for an explanation I recommend http://www.slideshare.net/league/monadologie ) Provided as a separate plug-in Look for continuations.jar in subfolder <scala2.8InstallDir>isccala-devellugins Page 64 defdos = reset { println("look here") valx = 2 + cont* 4 println(x) } defcont = shift {    k: (Int => Unit) =>  	      k(2) println("ok")       k(3)         }                //  => look here <cr> 10 <cr> 14 Use-P:continuations:enableas  Compiler argument !!!
Scala 2.8 in a Nutshell – Package Objects What is the problem? If you move entities of an existing package to another one, your imports are broken This can be prevented by package objects ... which represent collections of aliases Page 65 package object scala { // reference to class     type List[+A] =  scala.collection.immutable.List[A] // reference to companion object val List = scala.collection.immutable.List    … }
Scala 2.8 in a Nutshell – Case Classes  Case classes were refined For example, a copy method is now available Is helpful if you need copies of objects (maybe with minor changes) Page 66 case class Circle(val center: Point, val radius: Double) // now you can use: val c_orig = Circle(1.0,2.0) val c_clon = c_orig.copy(radius = 2.2)
Page 67 Scala Future
STM (Software Transactional Memory) Dealing with locking and thread-management is hard Agents are not a good solution for applications that share data This holds especially when combining multiple actions  In database management systems, transactions come to our rescue Same can be done in memory using STM ScalaSTM offers a good solution based on Clojure  Page 68 See also: http://www.scala-lang.org/node/8359
STM – The Idea Idea: Separate object from identity If object is going to be modified in a thread, let reference (identity) refer to new object Objects themselves remain unchanged If another thread has changed the object in the meantime roll back change otherwise commit change Page 69 Ref Object val x Object‘
Example Code without STM Page 70 object TestCounter {   var ctr = 0 // variable with no lock!   class IncrementerThread(howOften : Int) extends Thread {     override def run() {       for (m <- 0 until howOften) {           ctr += 1       }     } }   def runAll(nThreads : Int, howOften : Int) {     val pThreads = Array.tabulate(nThreads){_ => new                                      IncrementerThread(howOften) }     for (t <- pThreads) t.start()     for (t <- pThreads) t.join()   }   def main(args: Array[String]) {  runAll(100, 100)      println("RESULT  " + ctr)   } }  // result will be usually less than 10000 due to raise conditions
package scala.concurrent.stm object TestCounter { val ctr = Ref(0)   class IncrementerThread(howOften : Int) extends Thread {     override def run() {       for (m <- 0 until howOften) { atomic { implicit txn =>           ctr += 1         }       }     }   }   def runAll(nThreads : Int, howOften : Int) {     val pThreads = Array.tabulate(nThreads){_ => new                                 IncrementerThread(howOften) }     for (t <- pThreads) t.start()     for (t <- pThreads) t.join()   }   def main(args: Array[String]) {   runAll(100, 100)     println("RESULT  " + ctr.single()) }  // will always result in 10000 }  Example Code with STM ScalaSTM library Defining a ref Access to refs  only in atomic  transaction blocks Allow single op transaction Page 71
STM Additional Features retry in atomic block allows to roll back and wait until input conditions change: Waiting for multiple events: if upper block retries, control is transferred to lower block: Page 72 def maybeRemoveFirst(): Option[Int] = { atomic { implicit txn =>       Some(removeFirst())     } orAtomic { implicit txn =>       None     }   } // note: header.next and // header.prev are refs def removeFirst(): Int = atomic { implicit txn =>     val n = header.next()     if (n == header) retry     val nn = n.next()     header.next() = nn     nn.prev() = header     n.elem   }
Homework for testing your Scala capabilities Try to read through the following example and figure out what it does and how it does what it does Page 73
A more advanced Scala example (1)  (from Venkat Subramanian‘s book Programming Scala, pp.5) Page 74 import scala.actors._ import Actor._ val symbols = List( "AAPL", "GOOG", "IBM", "JAVA", "MSFT") val receiver = self val year = 2009 symbols.foreach {    symbol =>  actor { receiver ! getYearEndClosing(symbol, year) } } val (topStock, highestPrice) = getTopStock(symbols.length) printf("Top stock of %d is %s closing at price %f", 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("")(1).split(",")(4).toDouble       (symbol, price) } // .. to be continued
A more advanced Scala example (2)(from Venkat Subramanian‘s book Programming Scala, pp.5) Run this within interpreter mode scala TopScala.scala After the end of the talk return to this example and check whether you better understand it Page 75 // 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 Installation & Use Download distribution from http://www.scala-lang.org You may use Scala Compilers: scalac and fsc Eclipse, JetBrains, NetBeans Plug-In REPL (Read-Eval-Print-Loop) shell: scala I have tested these on Windows {XP, Vista, 7} 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: http://liftweb.net/ Page 76

Weitere ähnliche Inhalte

Was ist angesagt? (19)

C# in depth
C# in depthC# in depth
C# in depth
 
(2) c sharp introduction_basics_part_i
(2) c sharp introduction_basics_part_i(2) c sharp introduction_basics_part_i
(2) c sharp introduction_basics_part_i
 
Javascript
JavascriptJavascript
Javascript
 
DIWE - Fundamentals of PHP
DIWE - Fundamentals of PHPDIWE - Fundamentals of PHP
DIWE - Fundamentals of PHP
 
Object Oriented Programming using C++ Part III
Object Oriented Programming using C++ Part IIIObject Oriented Programming using C++ Part III
Object Oriented Programming using C++ Part III
 
Why Java Sucks and C# Rocks (Final)
Why Java Sucks and C# Rocks (Final)Why Java Sucks and C# Rocks (Final)
Why Java Sucks and C# Rocks (Final)
 
Oops presentation
Oops presentationOops presentation
Oops presentation
 
Introduction to C++
Introduction to C++Introduction to C++
Introduction to C++
 
ParaSail
ParaSail  ParaSail
ParaSail
 
Modern C++
Modern C++Modern C++
Modern C++
 
DITEC - Programming with Java
DITEC - Programming with JavaDITEC - Programming with Java
DITEC - Programming with Java
 
C++ oop
C++ oopC++ oop
C++ oop
 
Swift, swiftly
Swift, swiftlySwift, swiftly
Swift, swiftly
 
C# / Java Language Comparison
C# / Java Language ComparisonC# / Java Language Comparison
C# / Java Language Comparison
 
Scala
ScalaScala
Scala
 
Java8
Java8Java8
Java8
 
C++ Programming
C++ ProgrammingC++ Programming
C++ Programming
 
Python Programming
Python ProgrammingPython Programming
Python Programming
 
C by balaguruswami - e.balagurusamy
C   by balaguruswami - e.balagurusamyC   by balaguruswami - e.balagurusamy
C by balaguruswami - e.balagurusamy
 

Ähnlich wie Qcon2011 functions rockpresentation_scala

Stepping Up : A Brief Intro to Scala
Stepping Up : A Brief Intro to ScalaStepping Up : A Brief Intro to Scala
Stepping Up : A Brief Intro to ScalaDerek Chen-Becker
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Martin Odersky
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: NotesRoberto Casadei
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Languageleague
 
Getting Started With Scala
Getting Started With ScalaGetting Started With Scala
Getting Started With ScalaMeetu Maltiar
 
Scala uma poderosa linguagem para a jvm
Scala   uma poderosa linguagem para a jvmScala   uma poderosa linguagem para a jvm
Scala uma poderosa linguagem para a jvmIsaias Barroso
 
A (too) Short Introduction to Scala
A (too) Short Introduction to ScalaA (too) Short Introduction to Scala
A (too) Short Introduction to ScalaRiccardo Cardin
 
How Scala promotes TDD
How Scala promotes TDDHow Scala promotes TDD
How Scala promotes TDDShai Yallin
 
BCS SPA 2010 - An Introduction to Scala for Java Developers
BCS SPA 2010 - An Introduction to Scala for Java DevelopersBCS SPA 2010 - An Introduction to Scala for Java Developers
BCS SPA 2010 - An Introduction to Scala for Java DevelopersMiles Sabin
 
An Introduction to Scala for Java Developers
An Introduction to Scala for Java DevelopersAn Introduction to Scala for Java Developers
An Introduction to Scala for Java DevelopersMiles Sabin
 
Scala Reflection & Runtime MetaProgramming
Scala Reflection & Runtime MetaProgrammingScala Reflection & Runtime MetaProgramming
Scala Reflection & Runtime MetaProgrammingMeir Maor
 

Ähnlich wie Qcon2011 functions rockpresentation_scala (20)

Stepping Up : A Brief Intro to Scala
Stepping Up : A Brief Intro to ScalaStepping Up : A Brief Intro to Scala
Stepping Up : A Brief Intro to Scala
 
Scala - core features
Scala - core featuresScala - core features
Scala - core features
 
Scala in a nutshell by venkat
Scala in a nutshell by venkatScala in a nutshell by venkat
Scala in a nutshell by venkat
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009
 
Scala presentationjune112011
Scala presentationjune112011Scala presentationjune112011
Scala presentationjune112011
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: Notes
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Language
 
Getting Started With Scala
Getting Started With ScalaGetting Started With Scala
Getting Started With Scala
 
Getting Started With Scala
Getting Started With ScalaGetting Started With Scala
Getting Started With Scala
 
Scala idioms
Scala idiomsScala idioms
Scala idioms
 
Scala uma poderosa linguagem para a jvm
Scala   uma poderosa linguagem para a jvmScala   uma poderosa linguagem para a jvm
Scala uma poderosa linguagem para a jvm
 
A (too) Short Introduction to Scala
A (too) Short Introduction to ScalaA (too) Short Introduction to Scala
A (too) Short Introduction to Scala
 
How Scala promotes TDD
How Scala promotes TDDHow Scala promotes TDD
How Scala promotes TDD
 
Scala ntnu
Scala ntnuScala ntnu
Scala ntnu
 
Workshop Scala
Workshop ScalaWorkshop Scala
Workshop Scala
 
BCS SPA 2010 - An Introduction to Scala for Java Developers
BCS SPA 2010 - An Introduction to Scala for Java DevelopersBCS SPA 2010 - An Introduction to Scala for Java Developers
BCS SPA 2010 - An Introduction to Scala for Java Developers
 
An Introduction to Scala for Java Developers
An Introduction to Scala for Java DevelopersAn Introduction to Scala for Java Developers
An Introduction to Scala for Java Developers
 
Scala Reflection & Runtime MetaProgramming
Scala Reflection & Runtime MetaProgrammingScala Reflection & Runtime MetaProgramming
Scala Reflection & Runtime MetaProgramming
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
First fare 2010 java-introduction
First fare 2010 java-introductionFirst fare 2010 java-introduction
First fare 2010 java-introduction
 

Kürzlich hochgeladen

Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdfInclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdfTechSoup
 
Measures of Position DECILES for ungrouped data
Measures of Position DECILES for ungrouped dataMeasures of Position DECILES for ungrouped data
Measures of Position DECILES for ungrouped dataBabyAnnMotar
 
Presentation Activity 2. Unit 3 transv.pptx
Presentation Activity 2. Unit 3 transv.pptxPresentation Activity 2. Unit 3 transv.pptx
Presentation Activity 2. Unit 3 transv.pptxRosabel UA
 
Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17Celine George
 
Millenials and Fillennials (Ethical Challenge and Responses).pptx
Millenials and Fillennials (Ethical Challenge and Responses).pptxMillenials and Fillennials (Ethical Challenge and Responses).pptx
Millenials and Fillennials (Ethical Challenge and Responses).pptxJanEmmanBrigoli
 
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)lakshayb543
 
Expanded definition: technical and operational
Expanded definition: technical and operationalExpanded definition: technical and operational
Expanded definition: technical and operationalssuser3e220a
 
How to Add Barcode on PDF Report in Odoo 17
How to Add Barcode on PDF Report in Odoo 17How to Add Barcode on PDF Report in Odoo 17
How to Add Barcode on PDF Report in Odoo 17Celine George
 
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17Celine George
 
Student Profile Sample - We help schools to connect the data they have, with ...
Student Profile Sample - We help schools to connect the data they have, with ...Student Profile Sample - We help schools to connect the data they have, with ...
Student Profile Sample - We help schools to connect the data they have, with ...Seán Kennedy
 
ROLES IN A STAGE PRODUCTION in arts.pptx
ROLES IN A STAGE PRODUCTION in arts.pptxROLES IN A STAGE PRODUCTION in arts.pptx
ROLES IN A STAGE PRODUCTION in arts.pptxVanesaIglesias10
 
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...Postal Advocate Inc.
 
The Contemporary World: The Globalization of World Politics
The Contemporary World: The Globalization of World PoliticsThe Contemporary World: The Globalization of World Politics
The Contemporary World: The Globalization of World PoliticsRommel Regala
 
EMBODO Lesson Plan Grade 9 Law of Sines.docx
EMBODO Lesson Plan Grade 9 Law of Sines.docxEMBODO Lesson Plan Grade 9 Law of Sines.docx
EMBODO Lesson Plan Grade 9 Law of Sines.docxElton John Embodo
 
ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...
ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...
ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...JojoEDelaCruz
 

Kürzlich hochgeladen (20)

YOUVE GOT EMAIL_FINALS_EL_DORADO_2024.pptx
YOUVE GOT EMAIL_FINALS_EL_DORADO_2024.pptxYOUVE GOT EMAIL_FINALS_EL_DORADO_2024.pptx
YOUVE GOT EMAIL_FINALS_EL_DORADO_2024.pptx
 
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdfInclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
 
Measures of Position DECILES for ungrouped data
Measures of Position DECILES for ungrouped dataMeasures of Position DECILES for ungrouped data
Measures of Position DECILES for ungrouped data
 
Presentation Activity 2. Unit 3 transv.pptx
Presentation Activity 2. Unit 3 transv.pptxPresentation Activity 2. Unit 3 transv.pptx
Presentation Activity 2. Unit 3 transv.pptx
 
FINALS_OF_LEFT_ON_C'N_EL_DORADO_2024.pptx
FINALS_OF_LEFT_ON_C'N_EL_DORADO_2024.pptxFINALS_OF_LEFT_ON_C'N_EL_DORADO_2024.pptx
FINALS_OF_LEFT_ON_C'N_EL_DORADO_2024.pptx
 
Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17
 
Millenials and Fillennials (Ethical Challenge and Responses).pptx
Millenials and Fillennials (Ethical Challenge and Responses).pptxMillenials and Fillennials (Ethical Challenge and Responses).pptx
Millenials and Fillennials (Ethical Challenge and Responses).pptx
 
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
 
LEFT_ON_C'N_ PRELIMS_EL_DORADO_2024.pptx
LEFT_ON_C'N_ PRELIMS_EL_DORADO_2024.pptxLEFT_ON_C'N_ PRELIMS_EL_DORADO_2024.pptx
LEFT_ON_C'N_ PRELIMS_EL_DORADO_2024.pptx
 
Expanded definition: technical and operational
Expanded definition: technical and operationalExpanded definition: technical and operational
Expanded definition: technical and operational
 
How to Add Barcode on PDF Report in Odoo 17
How to Add Barcode on PDF Report in Odoo 17How to Add Barcode on PDF Report in Odoo 17
How to Add Barcode on PDF Report in Odoo 17
 
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
 
Student Profile Sample - We help schools to connect the data they have, with ...
Student Profile Sample - We help schools to connect the data they have, with ...Student Profile Sample - We help schools to connect the data they have, with ...
Student Profile Sample - We help schools to connect the data they have, with ...
 
ROLES IN A STAGE PRODUCTION in arts.pptx
ROLES IN A STAGE PRODUCTION in arts.pptxROLES IN A STAGE PRODUCTION in arts.pptx
ROLES IN A STAGE PRODUCTION in arts.pptx
 
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
 
Paradigm shift in nursing research by RS MEHTA
Paradigm shift in nursing research by RS MEHTAParadigm shift in nursing research by RS MEHTA
Paradigm shift in nursing research by RS MEHTA
 
The Contemporary World: The Globalization of World Politics
The Contemporary World: The Globalization of World PoliticsThe Contemporary World: The Globalization of World Politics
The Contemporary World: The Globalization of World Politics
 
INCLUSIVE EDUCATION PRACTICES FOR TEACHERS AND TRAINERS.pptx
INCLUSIVE EDUCATION PRACTICES FOR TEACHERS AND TRAINERS.pptxINCLUSIVE EDUCATION PRACTICES FOR TEACHERS AND TRAINERS.pptx
INCLUSIVE EDUCATION PRACTICES FOR TEACHERS AND TRAINERS.pptx
 
EMBODO Lesson Plan Grade 9 Law of Sines.docx
EMBODO Lesson Plan Grade 9 Law of Sines.docxEMBODO Lesson Plan Grade 9 Law of Sines.docx
EMBODO Lesson Plan Grade 9 Law of Sines.docx
 
ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...
ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...
ENG 5 Q4 WEEk 1 DAY 1 Restate sentences heard in one’s own words. Use appropr...
 

Qcon2011 functions rockpresentation_scala

  • 1. Functions rock!Harnessing the Power of Functional Part I: Programming with Scala TUTORIAL QCON 2011, London Prof. Dr. Michael Stal Michael.Stal@siemens.com
  • 2. Objectives of Presentation Introducing core concepts of Functional Programming Introducing Scala as example Presentingthe benefits of combining OO and functional programming Illustrating the language in a pragmatic way preferring code over theory But not to cover every available aspect or to cover aspects in full detail Page 2
  • 3. Whatis Functional Programming? Praise the Lambda Calculus (which is almost 80 years old) and its successors (e.g., the typed ones) (Mathematical) Functions Are a means of decomposition Can be assigned to variables Can be passed as arguments to or returned from functions Can be anonymous (closures) Emphasize on Immutability: No side-effects of functions (referential transparency) Values instead of variables Page 3
  • 4. Functional ProgrammingLanguages … Are oftenhybrid such as Lisp/Clojure, F#, Scala Use Recursion instead of Iteration Can be strict (eager) or non-strict (lazy) Use mainly the Typed Lambda Calculus and thus support Pattern Matching Support concepts such as Monads, Continuations Integrate Comprehensions for collection types, Catamorphisms (fold), Anamorphisms (unfold) Page 4
  • 5. Preconception: Functional LanguagesareSlow Isnottrueanymoredue to: HighlyefficientVMslikethe CLR, JVM StructuralSharing, no naive copying TailCallOptimization: at least someVMs Veryefficient and powerfulLibraries Easy leveraging of Concurrency (e.g., because of immutablity) Page 5
  • 6. Object-Oriented & Functional Programming Object-Oriented Programming Abstraction using Classes and Interfaces Refinement using subtyping and inheritance (Remember the Liskov Substitution Principle!) Dynamics through polymorphism Functional Programming Higher Order Functions as First-Class Entities ADTs (Abstract Data Types) following algebraic conventions Pattern matching Parametric polymorphism (generic types) Page 6 SCALA
  • 7. Introduction to Scala 2.8.x Scala created by the team of Martin Odersky at EPFL „Scala“ means „Scalable Language“ „Scalable“ means: the same language concepts for programming in the small & large In Scala this is achieved in a pragmatic way by combining Object Oriented Programming with Functional Programming Scala is a statically typed language like Java All types are objects Page 7 Martin Odersky, Source: http://lamp.epfl.ch/~odersky/
  • 8.
  • 11. ML
  • 12.
  • 13. Stairway to Heaven – First Steps using Scala This source code file may be compiled using scalac und run using scala: scalac HelloWorldMain.scala scala 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 instead scala 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 Eclipse Page 10
  • 14. Scala Type Hierarchy Page 11 Scala uses a pure object-oriented type system Every value is an object Two types: values and references Any is parent class of all classes, Nothing subclass of all classes Basic types like in Java Source: Scala Reference Manual
  • 15. First Class Scala Page 12 born and id will be public fields Main constructor Classes in Scala contain fields, methods, types, constructors Visibility is public per default class CatID(val id : Int) //that's a whole class class Cat(val born: Int, val id: CatID) { private var miceEaten: Int = 0 def digested() = miceEaten def 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 <> Tom was born in 2010 definition of methods No brackets required
  • 16. Class Constructors Page 13 class 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 to Primary constructor Auxilliary constructorsmust call primary
  • 17. Immutable and Mutable Objects Scala provides immutable objects (functional programming) but also mutable objects Immutability has many benefits Reduction of race conditions in concurrent programs Protection against unwanted modification Scala provides mutable & immutable versions of collection types Mutable objects are important to address objects that are supposed to change their state, but use them with care Page 14 class Person(var name: String) object ImmutabilityDemo { def main(args:Array[String]) = { val s = "Michael" s = "Bill" // error var t = "Michael“ // t variable t = "Bill" // ok val c = new Person("Bill") c = new Person("Tom") // error // ok - c itself unchanged: c.name = "Tom" } }
  • 18. Inheritance In Scala classes can be derived from at most one base class Classes may be abstract You need to indicate whether you override inherited methods Page 15 abstractclass 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" }
  • 19. Companion Objects and Standalone Objects We already saw standalone objects Objects are singletons If you need static fields or methods for a class, introduce a companion class with the same name Convention: apply() methods may be provided as factory methods Page 16 class Cat private (val born : Int, val id: CatID) { ... private def this(id: CatID) = this(2010, id) ... } // all constructors are private object Cat { // this is the companion object of Cat def 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 } }
  • 20. Application Base Class For experimenting with Scala use the base class Application Just compile this with: scalac ObjDemo.scala And run it with: scala ObjDemo Useful abbreviation if you do not need to deal with command line arguments Page 17 Inheritance object ObjDemoextends Application { val s: String = "Michael" println(s) // => Michael }
  • 21. Traits Classes and instances may mix-in additional functionality using traits Traits represent an abstraction between interfaces and classes Using traits we can easily live with the single-inheritance restriction You may use also traits via anonymous classes: val x = new Identity{} x.name = "UFO" println(x.whoAmI) Page 18 trait Identity { var name: String="" def whoAmI() : String = name } class Person(var name: String) extends Identity class Animal object 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 <> Kittie
  • 22. Traits and Virtual Super: Inheritance Linearization Page 19 abstract class Processor { def process() } trait Compressor extends Processor { // trait only applicable to Processor subclass abstract override def process() = { println("I am compressing"); super.process } } trait Encryptor extends Processor { // only applicable to Processor subclass abstract 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 Encryptor proc1.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!
  • 23. Scala Basics: if Statements If statements are expressions themselves, i.e. they have values Page 20 import 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!"
  • 24. 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 elements Page 21 val aList = List(1,2,3,4,5,6) for (i <- aList) println(i) // => 1 <> 2 ... val dogs = Set("Lassie", "Lucy", "Rex", "Prince"); for (a <- dogs if a.contains("L")) println(a) // => “Lassie” <> “Lucy”
  • 25. Scala Basics: for Comprehensions (2) Yield allows to create new collections in a for comprehension: You can specify filters for the collection elements Page 22 var newSet = for { a <- dogs if a.startsWith("L") } yield a println(newSet) // Set(Lassie, Lucy) for { i <- List(1,2,3,4,5,6) j = i * 2 // new variable j defined } println(j) // => 2 <> 4 <> 6 ...
  • 26. Scala Basics: Other loops Scala supports while and do-while loops But generator expressions such as (1 to 6) incl. 6 or (1 until 6) excl. 6 together with for make this much easier Note: 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 comprehensions Page 23 var i = 1 while (i <= 6) { println(i) i += 1 } // = 1 <> 2 <> 3 ... for (i <- 1 to 6) println(i)
  • 27. Scala Basics: Exception handling try-catch-finally available in Scala but throws isn‘t catching checked exceptions is optional! catch-order important as in Java, C++ or C# Page 24 def 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") }
  • 28. Inner Classes You may define inner classes as in Java Special notation (<name> =>) for referring to outer class this from an inner class: you might also use <outerclass>.this instead Page 25 class Element (val id: String){ elem => class Properties { // inner class type 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 +"" s } } override def toString = "ID = " + id + "" + 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) }
  • 29.
  • 30. import p.{x => a} the member x of p renamed as a.
  • 31. import p.{x, y} the members x and y of p.
  • 32.
  • 33. Advanced Types: Sets Collection Type: Set Page 28 object 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)) // => true val s3 = s1 ++ s2 // union println(s3) // => Set(5,7,3,1,4,2) vals4 = s1 & s2 // intersection: in earlier versions ** println(s4) // Set(5,3,2) } }
  • 34. Advanced Types: Maps Collection Type: Map Page 29 object MapDemo { def main(args:Array[String]) { val m1 = Map[Int, String](1 -> "Scala", 2->"Java", 3->"Clojure") valm2 = m1 + (4 -> "C#") // add entry println(m2 + " has size " + m2.size) //=> Map(1->Scala,…) has size 4 println(m1(1)) // => Scala val m3 = m2 filter { element => val (key, value) = element (value contains "a") } println(m3) // => Map(1->Scala, w->Java) } }
  • 35. Advanced Types: Options object 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“) <> None } The Option type helps dealing with optional values For instance, a search operation might return a result or nothing We are also introducing Enumerationtypes Page 30
  • 36. Advanced Types: Regular Expressions Type: Regex introduces well-known regular expressions Page 31 With this syntax strings remain formatted as specified and escape sequences are not required object RegDemo { def main(args:Array[String]) { val pattern = """""".r val 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
  • 37. Advanced Types: Tuples Tuples combine fixed number of Elements of various types Thus, you are freed from creating heavy-weight classes for simple aggregates Page 32 println( (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
  • 38. Advanced Types: Arrays Arrays hold sequences of elements Access very efficient Page 33 val a1 = new Array[Int](5) // initialized with zeros val a2 = Array(1,2,3,4,5) // initialized with 1,2,3,4,5 println( a2(1) ) // => 2 a2(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
  • 39. Smooth Operator In Scala operator symbols are just plain method names For instance 1 + 2 stands for 1.+(2) Precedence rules: All letters | ^ & < > = ! : + - * / % Page 34 class 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)
  • 40. Conversions Implicit converters allow Scala to automatically convert data types Suppose, you‘d like to introduce a mathematical notatation such as 10! Using implicit type converters you can easily achieve this Page 35 object 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
  • 41. Parameterized Types in Scala Classes, Traits, Functions may be parameterized with types In contrast to Java no wildcards permitted – parameter types must have names Variance specification allow to specify covariance and contravariance Page 36 trait 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)
  • 42. Small Detour to Variance and Covariance / Type Bounds If 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 way Example List[+T]: Covariance means a List[Int] can be assigned to a List[Any] because Int is subtype of Any Upper/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 37
  • 43. Functional Aspects: Functions and Closures In Scala Functions are First-Class Citizens They can be passed as arguments assigned to variables: val closure={i:Int => i+42} Nested functions are also supported Page 38 object 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 )) } } => 55 5
  • 44. Functional Aspects: Call-by-Name If a parameterless closure is passed as an argument to a function, Scala will evaluate the argument when the argument is actually used This is in contrast to call-by-value arguments A similar effect can be achieved using lazy (value) evaluation: lazy val = <expr> Page 39 import java.util._ object CbNDemo { def fun(v: => Int) : Int = v // v is a Call-by-Name Parameter def v() : Int = new Random().nextInt(1000) def main(args:Array[String]) { println( fun(v) ) println( fun(v) ) } } // => 123 <> 243
  • 45. 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 40 object scalafunctions { def fun1(i:Int, j:Int) : Int = i + j def 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
  • 46. Functional Aspects: Currying (2) Currying helps increase readability Take foldleft as an example Page 41 FoldLeft Operator val x = (0 /: (1 to 10)) { (sum, elem) => sum + elem } // 55 Carryover value for next iteration Function arguments Carryover value Collection For each iteration, foldleft passes the carry over value and the current collection element. We need to provide the operation to be applied This is collection which we iterate over This is the value that is updated in each iteration Think how this would be implemented in Java!
  • 47. Positional Parameters If you use a parameter only once, you can use positional notation of parameters with _ (underscore) instead Page 42 object scalafunctions { def main(args:Array[String]) { val seq= (1 to 10) println( (0 /: seq) { (sum, elem) => sum + elem } ) println( (0 /: seq) { _ + _ } ) } }
  • 48. Using the features we can build new DSLs and additional features easily The following loop-unless example is from the Scala tutorial Page 43 object 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 loop with this body ... and invoking unless on the result
  • 49. Functional Aspect: Partially Applied Functions If you only provide a subset of arguments to a function call, you actually retrieve a partially defined function Only the passed arguments are bound, all others are not In a call to a partially applied function you need to pass the unbound arguments All this is useful to leverage the DRY principle when passing the same arguments again and again Page 44 object 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 } }
  • 50. 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 objects Basically, each function is identical to a class with an apply method Thus, you can even derive subclasses from functions Array is an example for this: class Array [T] (length: Int ) extends (Int => T) { def length: Int = ... Page 45
  • 51. Functional Aspects: Pattern Matching Pattern matching allows to make a pragmatic choice between various options Page 46 valaNumber = 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) }
  • 52. Functional Aspects: Matching on Types It is also possible to differentiate by type: Page 47 object 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 <> 1 <> OOP <> Something else
  • 53. Functional Aspects: Matching on Lists Lists can be easily used with Pattern Matching: Page 48 object 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 <> 3 on 3 <> List with starting 1 <> Other List
  • 54. Functional Aspects: Matching on Tuples So do Tuples: Page 49 object TupleCase { def matcher(t : Tuple2[String,String]) { t match { case („QCON",s) => println(„QCON " + s) case ("Scala", s) => println("Scala " + s) case _ => println("Other Tuple") } } def main(args: Array[String]) { matcher(„QCON", "2011") matcher("Scala", "rocks"); matcher("A","B") } } => QCON 2011 <> Scala rocks >cr> Other Tuple
  • 55. Functional Aspects: Matching on Case Classes Case Classes are immutable classes for which the compiler generates additional functionality to enable pattern matching, e.g., an apply() method: Page 50 sealed abstract class Shape // sealed => subclasses only in this source file case class Circle(val center: Point, val radius: Double) extends Shape case class Line(val pt1: Point, val pt2: Point) extends Shape case 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))) } } There are also case objects !!!
  • 56. Functional Aspect: Extractors Extractors are objects with an unapply method used to match a value and partition it into constituents – an optional apply is used for synthesis Page 51 object EMail { def apply(prefix: String, domain: String) = prefix + "@" + domain def 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") } } }
  • 57. Partial Functions Partial Functions are not defined for all domain values Can be asked with isDefinedAt whether a domain value is accepted Example: Blocks of Pattern Matching Cases Page 52 trait PartialFunction[-D, +T] extends (D => T) { def isDefinedAt(x: D): Boolean }
  • 58. Actors by Example Page 53 ! Note: react & receive have cousins with timeout arguments: receiveWithin and reactWithin import 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 actor Calculator ! "exit" }
  • 59. Processing XML in Scala Scala can directly handle XML With package scala.xml we can read, parse, create and store XML documents XPath like query syntax Page 54 import scala.xml._ // in our example not required object XMLDemo extends Application { val x : scala.xml.Elem = <conferences> <conference name=„QCON"> <year> 2011 </year> </conference> <conference name=„GOTO"> <year> 2011 </year> </conference> </conferences> var conferenceNodes = x "conference„ // get all conference nodes for (c <- conferenceNodes) println( cquot;@name“ ) // get attribute } // => OOP <> SET
  • 60. Accessing the Web with Scala You may use a mixture of Java and Scala code to access the Web Suppose, you‘d like to read a Web Page Here is an example how this might work Page 55 import 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 } }
  • 61. Combinator Parsing Scala allows to implement DSL parsers (LL(1)) For basic elements such as symbols, floats, strings etc. lexers are provided Developers can provide their own Let us use a simple example: a language that defines polygons as lists of points such as [(-1,0)(0,1)(+1,0)] which represents a triangle The grammar is pretty simple: poly ::= coord * coord ::= “(“ number “,“ number “)“ number aka floatingPointNumber is predefined Page 56
  • 62. Build the Parser in Scala - Part I Page 57 import scala.util.parsing.combinator._ class PolygonParserClass1 extends JavaTokenParsers { def poly : Parser[Any] = "["~rep(point)~"]" def point : Parser[Any] = "("~floatingPointNumber~","~floatingPointNumber~")" } object PolygonParser1 extends PolygonParserClass1 { def parse (input: String) = parseAll(poly, input) } object ParserDemo extends Application { println(PolygonParser1.parse("[(1,2)(3,7)]")) } => parsed: (([~List((((((~1)~,)~2)~)), (((((~3)~,)~7)~))))~]) ~ : sequence ~> : ignore left side of production rep( ) : repetition <~ : ignore right side of production opt() : option | ; alternative
  • 63. Build the Parser in Scala - Part 2 Page 58 Now, we would like to produce some code instead of just syntax checking We can add actions using ^^ case class Point(x : Float, y : Float) class PolygonParserClass2 extends JavaTokenParsers { def poly : Parser[List[Point]] = "["~>rep(coor)<~"]" ^^ { List[Point]() ++ _ } def coor : Parser[Point] = "("~floatingPointNumber~","~floatingPointNumber~")" ^^ { case "("~x~","~y~")" => Point(x.toFloat,y.toFloat) } } object PolygonParser2 extends PolygonParserClass2 { def parse (input: String) = parseAll(poly, input) } object ParserDemo extends Application { println(PolygonParser2.parse("[(1,2)(3,7)]")) } => parsed: List(Point(1.0,2.0), Point(3.0,7.0))
  • 64. New in Version 2.8: Packrat Parsers Page 59 With Packrat parsers you can handle left recursion In addition parsing is possible in constant time but unlimited lookahead import scala.util.parsing.combinator._ import scala.util.parsing.input.CharArrayReader case class Point(x : Float, y : Float) object PackratParserDemo extends JavaTokenParsers with PackratParsers { lazy val poly : Parser[List[Point]] = "["~>rep(coor)<~"]" ^^ { List[Point]() ++ _ } lazy val coor : Parser[Point] = "("~floatingPointNumber~","~floatingPointNumber~")" ^^ { case "("~x~","~y~")" => Point(x.toFloat,y.toFloat) } } object ParserDemo extends Application { println(PackratParserDemo.phrase(PackratParserDemo.poly) (new CharArrayReader("[(1,2)(4,5)]".toCharArray))) }=> parsed: List(Point(1.0,2.0), Point(4.0,5.0))
  • 65. What is new in Scala 2.8.x So far we covered basically Scala 2.7 In the meantime, the new Scala version 2.8 is available with some improvements, e.g.: collection library has been reorganized and optimized tools improvements such as for REPL performance improvements For details around Scala 2.8 refer to http://www.scala-lang.org/node/198 Let me provide main changes of Scala version 2.8 in a Nutshell see also Dean Wampler‘s blog: http://blog.objectmentor.com/articles/2009/06/05/bay-area-scala-enthusiasts-base-meeting-whats-new-in-scala-2-8 Page 60
  • 66. Scala 2.8 in a Nutshell - Default arguments Default arguments get a default value Page 61 object O { def charge(amount: Double, Currency : String = “GBP"){ // do whatever necessary to get the money println(amount + " " + Currency) } def main(args : Array[String]) : Unit = { charge (200.0) charge (120.67, "EUR") } }
  • 67. Scala 2.8 in a Nutshell - Named arguments Named arguments help to call methods without being constrained by order of arguments Page 62 object O { def welcome(firstName: String, lastName : String){ println("Hello " + firstName + " " + lastName) } def main(args : Array[String]) : Unit = { welcome(lastName= “Duck“, firstName = “Donald") } }
  • 68. Scala 2.8 in a Nutshell - Annotations Annotations can be nested: @specialized annotation: Scala generics are fully specified at declaration place with a uniform implementation. This reduced performance for „primitive“ types (i.e., those derived from AnyVal). The annotation forces the compiler to generate an optimized version of the Generic for such types: Page 63 @ExcellentClass(arg= @AuthorDetails) def m[@specialized T](x: T, f: T => T) = f(x) m(2, (x:Int) => x * 2)
  • 69. Scala 2.8 in a Nutshell - Continuations Continuations are the most difficult to understand feature ( for an explanation I recommend http://www.slideshare.net/league/monadologie ) Provided as a separate plug-in Look for continuations.jar in subfolder <scala2.8InstallDir>isccala-devellugins Page 64 defdos = reset { println("look here") valx = 2 + cont* 4 println(x) } defcont = shift { k: (Int => Unit) => k(2) println("ok") k(3) } // => look here <cr> 10 <cr> 14 Use-P:continuations:enableas Compiler argument !!!
  • 70. Scala 2.8 in a Nutshell – Package Objects What is the problem? If you move entities of an existing package to another one, your imports are broken This can be prevented by package objects ... which represent collections of aliases Page 65 package object scala { // reference to class type List[+A] = scala.collection.immutable.List[A] // reference to companion object val List = scala.collection.immutable.List … }
  • 71. Scala 2.8 in a Nutshell – Case Classes Case classes were refined For example, a copy method is now available Is helpful if you need copies of objects (maybe with minor changes) Page 66 case class Circle(val center: Point, val radius: Double) // now you can use: val c_orig = Circle(1.0,2.0) val c_clon = c_orig.copy(radius = 2.2)
  • 72. Page 67 Scala Future
  • 73. STM (Software Transactional Memory) Dealing with locking and thread-management is hard Agents are not a good solution for applications that share data This holds especially when combining multiple actions In database management systems, transactions come to our rescue Same can be done in memory using STM ScalaSTM offers a good solution based on Clojure Page 68 See also: http://www.scala-lang.org/node/8359
  • 74. STM – The Idea Idea: Separate object from identity If object is going to be modified in a thread, let reference (identity) refer to new object Objects themselves remain unchanged If another thread has changed the object in the meantime roll back change otherwise commit change Page 69 Ref Object val x Object‘
  • 75. Example Code without STM Page 70 object TestCounter { var ctr = 0 // variable with no lock! class IncrementerThread(howOften : Int) extends Thread { override def run() { for (m <- 0 until howOften) { ctr += 1 } } } def runAll(nThreads : Int, howOften : Int) { val pThreads = Array.tabulate(nThreads){_ => new IncrementerThread(howOften) } for (t <- pThreads) t.start() for (t <- pThreads) t.join() } def main(args: Array[String]) { runAll(100, 100) println("RESULT " + ctr) } } // result will be usually less than 10000 due to raise conditions
  • 76. package scala.concurrent.stm object TestCounter { val ctr = Ref(0) class IncrementerThread(howOften : Int) extends Thread { override def run() { for (m <- 0 until howOften) { atomic { implicit txn => ctr += 1 } } } } def runAll(nThreads : Int, howOften : Int) { val pThreads = Array.tabulate(nThreads){_ => new IncrementerThread(howOften) } for (t <- pThreads) t.start() for (t <- pThreads) t.join() } def main(args: Array[String]) { runAll(100, 100) println("RESULT " + ctr.single()) } // will always result in 10000 } Example Code with STM ScalaSTM library Defining a ref Access to refs only in atomic transaction blocks Allow single op transaction Page 71
  • 77. STM Additional Features retry in atomic block allows to roll back and wait until input conditions change: Waiting for multiple events: if upper block retries, control is transferred to lower block: Page 72 def maybeRemoveFirst(): Option[Int] = { atomic { implicit txn => Some(removeFirst()) } orAtomic { implicit txn => None } } // note: header.next and // header.prev are refs def removeFirst(): Int = atomic { implicit txn => val n = header.next() if (n == header) retry val nn = n.next() header.next() = nn nn.prev() = header n.elem }
  • 78. Homework for testing your Scala capabilities Try to read through the following example and figure out what it does and how it does what it does Page 73
  • 79. A more advanced Scala example (1) (from Venkat Subramanian‘s book Programming Scala, pp.5) Page 74 import scala.actors._ import Actor._ val symbols = List( "AAPL", "GOOG", "IBM", "JAVA", "MSFT") val receiver = self val year = 2009 symbols.foreach { symbol => actor { receiver ! getYearEndClosing(symbol, year) } } val (topStock, highestPrice) = getTopStock(symbols.length) printf("Top stock of %d is %s closing at price %f", 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("")(1).split(",")(4).toDouble (symbol, price) } // .. to be continued
  • 80. A more advanced Scala example (2)(from Venkat Subramanian‘s book Programming Scala, pp.5) Run this within interpreter mode scala TopScala.scala After the end of the talk return to this example and check whether you better understand it Page 75 // 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
  • 81. Scala Installation & Use Download distribution from http://www.scala-lang.org You may use Scala Compilers: scalac and fsc Eclipse, JetBrains, NetBeans Plug-In REPL (Read-Eval-Print-Loop) shell: scala I have tested these on Windows {XP, Vista, 7} 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: http://liftweb.net/ Page 76
  • 82. Scala Test Scala Test offers a test framework for Scala Facilitates different flavors of testing: TestNG, JUnit4, JUnit3 Leverages the conciseness of Scala Official site: http://www.scalatest.org/ Latest version 1.2 Good presentation webcast with Bill Venners: http://www.parleys.com/#id=1552&st=5 Page 77
  • 83. specs provides BDD (Business-Driven Development) for Scala Main site: http://code.google.com/p/specs/ Good introductory presentation available in http://www.slideshare.net/etorreborre/oscon-2010-specs-talk Page 78
  • 84. Tools, tools, tools A lot of excellent tools and frameworks available: If you are interested in a Web Framework based on Scala use Lift: http://liftweb.net/ Use the sbt (simple-build-tool) as the ant-tool for Scala: http://code.google.com/p/simple-build-tool/ Use sbaz (Scala Bazaar) which is a package installation and maintenance system: it is already available in your Scala bin directory! Page 79
  • 85. Summary Scala combines the best of two worlds: OO and Functional Programming It runs on the JVM offering Java interop Actor library helps dealing with complexity of concurrent programming Scala programs are compact and concise => big productivity boost possible v2.8.x offers additional benefits such as named & default arguments, continuations More to come in v.2.9++ such as STM, Parallel Collections Scala is no island - many further tools and frameworks (e.g., Lift) available Coding with Scala is fun - Try it yourself! Page 80
  • 86. Books: My Recommendations M. 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! 2nd edition soon! V. Subramanian: Programming Scala: Tackle Multi-Core Complexity on the Java Virtual Machine (Pragmatic Programmers) (Paperback), Pragmatic Bookshelf (July 15, 2009) D. Wampler, 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 81