Your SlideShare is downloading. ×
0
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Oop2010 Scala Presentation Stal

5,312

Published on

This presentation offers a tutorial for introducing Scala. Readers should be familiar with C++, C# or Java

This presentation offers a tutorial for introducing Scala. Readers should be familiar with C++, C# or Java

Published in: Education
0 Comments
20 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,312
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
0
Comments
0
Likes
20
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Introduction toCoding in Scala is fun!<br />OOP 2010<br />Dr. Michael Stal<br />Michael.Stal@siemens.com<br />
  • 2. Objectives of this Presentation<br />Introduce core concepts of Scala<br />Showing you the benefits of combining OO with functional programming<br />Illustrating the language in a pragmatic way preferring code over theory<br />But not to cover every available aspect or to cover aspects in full detail<br />For instance, we won‘t cover Java/Scala Interop, Views, Equality Semantics, Unit Testing, Annotations<br />Page 2<br />
  • 3. Introduction<br />Scala created by the team of Martin Odersky at EPFL<br />„Scala“ means „Scalable Language“<br />„Scalable“ means: <br />the same language concepts for programming in the small &amp; large<br />In Scala this is achieved in a pragmatic way by combining <br />Object Oriented Programming with<br />Functional Programming <br />Scala is a statically typed language like Java<br />All types are objects<br />Page 3<br />Martin Odersky, Source: http://lamp.epfl.ch/~odersky/<br />
  • 4. Object-Oriented &amp; Functional Programming<br />Object-Oriented Programming<br />Abstraction using Classes and Interfaces<br />Refinement using subtyping and inheritance (Remember the Liskov Substitution Principle!)<br />Dynamics through polymorphism<br />Functional Programming<br />Higher Order Functions as First-Class Entities<br />ADTs (Abstract Data Types) following algebraic conventions<br />Pattern matching<br />Parametric polymorphism (generic types)<br />Page 4<br />SCALA<br />
  • 5. Core Properties of Scala (see Programming in Scala)<br />Scala is compatible: runs on JVM, interoperability with Java<br />Scala is concise: More compact code because removal of Java boilerplate code and powerful libraries<br />Scala is high-level: Higher level of abstraction by combining OO with functional programming<br />Scala is statically typed<br />Page 5<br />Scala‘s Roots:<br /><ul><li> Java, C#
  • 6. Smalltalk, Ruby
  • 7. Beta, Simula, Algol
  • 8. ML
  • 9. Erlang</li></li></ul><li>A small Appetizer - Hello, Scala!<br />Page 6<br />Type <br />Inference<br />Immutable values<br />Classes<br />class HelloWorldClass (val name: String) {<br /> def print() = println(&quot;Hello World of &quot; + name)<br />}<br />object HelloWorldMain {<br /> def main(args: Array[String]): Unit = {<br />val hello = new HelloWorldClass(&quot;Scala&quot;)<br /> hello print<br /> }<br />}<br />=&gt; Hello World of Scala<br />Singletons<br />Look Ma, <br />no semicolons<br />No brackets required!<br />
  • 10. Stairway to Heaven – First Steps using Scala <br />This source code file may be compiled using scalac und run using scala:<br />scalac HelloWorldMain.scala<br />scala HelloWorldMain <br />Note: the source file must be named like the main object to be executed <br />You may run an interpreter by using the following command line instead<br />scala HelloWorldMain.scala <br />In this case you may also use plain Scala scripts (no classes or objects required)<br />Or, even better, you might use an IDE like Idea, Netbeans, or Eclipse<br />Page 7<br />
  • 11. A more advanced example (1) (from Venkat Subramanian‘s book Programming Scala, pp.5)<br />Page 8<br />import scala.actors._<br />import Actor._<br />val symbols = List( &quot;AAPL&quot;, &quot;GOOG&quot;, &quot;IBM&quot;, &quot;JAVA&quot;, &quot;MSFT&quot;)<br />val receiver = self<br />val year = 2009<br />symbols.foreach { <br /> symbol =&gt; actor { receiver ! getYearEndClosing(symbol, year) }<br />}<br />val (topStock, highestPrice) = getTopStock(symbols.length)<br />printf(&quot;Top stock of %d is %s closing at price %f &quot;, year, topStock, highestPrice)<br />def getYearEndClosing(symbol : String, year : Int) = { <br /> val url = new <br /> java.net.URL(&quot;http://ichart.finance.yahoo.com/table.csv?s=&quot; +<br /> symbol + &quot;&amp;a=11&amp;b=01&amp;c=&quot; + year + &quot;&amp;d=11&amp;e=31&amp;f=&quot; + year + &quot;&amp;g=m&quot;) <br /> val data = io.Source.fromURL(url).mkString <br /> val price = data.split(&quot; &quot;)(1).split(&quot;,&quot;)(4).toDouble <br /> (symbol, price)<br />} // .. to be continued<br />
  • 12. A more advanced example (2)(from Venkat Subramanian‘s book Programming Scala, pp.5)<br />Run this within interpreter mode scala TopScala.scala<br />After the end of the talk return to this example and check whether you better understand it<br />Page 9<br />// continued ...<br />def getTopStock(count : Int) : (String, Double) = { <br /> (1 to count).foldLeft(&quot;&quot;, 0.0) { (previousHigh, index) =&gt; <br /> receiveWithin(10000) { <br /> case (symbol : String, price : Double) =&gt; <br /> if (price &gt; previousHigh._2) (symbol, price) <br /> else previousHigh <br /> } <br /> }<br />} <br />// will result in =&gt;<br />// Top stock of 2009 is GOOG closing at price 619,980000<br />
  • 13. Scala Type Hierarchy<br />Page 10<br />Scala uses a pure object-oriented type system<br />Every value is an object<br />Two types: values and references<br />Any is parent class of all classes, Nothing subclass of all classes<br />Basic<br />types like in<br />Java<br />Source: Scala Reference Manual<br />
  • 14. First Class Scala<br />Page 11<br />born and <br />id will be<br />public fields<br />Main constructor<br />Classes in Scala contain fields, methods, types, constructors<br />Visibility is public per default<br />class CatID(val id : Int) //that&apos;s a whole class<br />class Cat(val born: Int, val id: CatID) {<br />private var miceEaten: Int = 0<br /> def digested() = miceEaten<br />def hunt(miceCaught: Int) <br /> { miceEaten += miceCaught }<br />}<br />object ScalaClasses {<br /> def main(args: Array[String]) {<br /> val id = new CatID(42)<br /> val tom = new Cat(2010, id)<br /> tom.hunt(3)<br /> tom hunt 2<br /> println(“cat was born in “ + tom.born) <br /> println(tom.digested)<br /> }<br />} // =&gt; 5 &lt; &gt; Tom was born in 2010 <br />definition<br />of methods<br />No brackets<br />required<br />
  • 15. Class Constructors<br />Page 12<br />class Complex (r : Double, i: Double) {<br /> println(&quot;Constructing a complex number&quot;)<br /> val re = r<br /> val im = i<br /> def this(r : Double) = this(r,0)<br /> override def toString = <br /> re + (if (im &lt; 0) &quot;-&quot; + (-im) <br /> else &quot;+&quot; + im) + &quot;*i&quot;<br /> ...<br />}<br />Belongs to<br />Primary<br />constructor<br />Auxilliary<br />constructorsmust call<br />primary<br />
  • 16. Immutable and Mutable Objects<br />Scala provides immutable objects (functional programming) but also mutable objects<br />Immutability has many benefits<br />Reduction of race conditions in concurrent programs<br />Protection against unwanted modification<br />Scala provides mutable &amp; immutable versions of collection types<br />Mutable objects are important to address objects that are supposed to change their state, but use them with care<br />Page 13<br />class Person(var name: String)<br />object ImmutabilityDemo {<br /> def main(args:Array[String]) = {<br />val s = &quot;Michael&quot;<br /> s = &quot;Bill&quot; // error<br />var t = &quot;Michael“ // t variable<br /> t = &quot;Bill&quot; // ok<br /> val c = new Person(&quot;Bill&quot;)<br /> c = new Person(&quot;Tom&quot;) // error<br />// ok - c itself unchanged:<br /> c.name = &quot;Tom&quot;<br /> }<br />}<br />
  • 17. Inheritance<br />In Scala classes can be derived from at most one base class<br />Classes may be abstract<br />You need to indicate whether you override inherited methods<br />Page 14<br />abstractclass Shape {<br />type Identifier = Int // defining types<br /> def getID() : Identifier = 42<br /> def draw() : String // abstract method<br />}<br />class Circle (val cx: Double, val cy: Double, val r: Double) extends Shape {<br /> val id : Identifier = getID()<br />override def draw() : String = &quot;I am a Circle&quot;<br />}<br />
  • 18. Companion Objects and Standalone Objects<br />We already saw standalone objects<br />Objects are singletons<br />If you need static fields or methods for a class, introduce a companion class with the same name<br />Convention: apply() methods may be provided as factory methods<br />Page 15<br />class Cat private (val born : Int, val id: CatID) {<br /> ...<br />private def this(id: CatID) = this(2010, id)<br /> ...<br />} // all constructors are private<br />object Cat { // this is the companion object of Cat<br />def apply(born: Int, id: CatID) = new Cat(born, id)<br /> def apply(id: CatID) = new Cat(id) // factory method<br /> def whatCatsDo() = &quot;Sleep, eat, play&quot; <br />}<br />object ScalaClasses { // Standalone Object<br /> def main(args: Array[String]) {<br /> val id = new CatID(43)<br />val pussy = Cat(id) // no new required<br /> println(&quot;Pussy was born in &quot; + pussy.born)<br /> println(Cat.whatCatsDo) // like static in Java <br /> }<br />}<br />
  • 19. Application Base Class<br />For experimenting with Scala use the base class Application<br />Just compile this with: scalac ObjDemo.scala<br />And run it with: scala ObjDemo<br />Useful abbreviation if you do not need to deal with command line arguments<br />Page 16<br /> Inheritance<br />object ObjDemoextends Application {<br />val s: String = &quot;Michael&quot;<br />println(s) // =&gt; Michael<br />}<br />
  • 20. Traits<br />Classes and instances may mix-in additional functionality using traits<br />Traits represent an abstraction between interfaces and classes<br />Using traits we can easily live with the single-inheritance restriction<br />You may use also traits via anonymous classes:<br /> val x = new Identity{}<br /> x.name = &quot;UFO&quot;<br /> println(x.whoAmI)<br />Page 17<br />trait Identity {<br /> var name: String=&quot;&quot;<br /> def whoAmI() : String = name <br />}<br />class Person extends Identity <br />class Animal<br />object TraitDemo {<br /> def main(args:Array[String]) = {<br /> val p = new Person<br /> p.name = &quot;Michael&quot;<br /> println(p.whoAmI)<br />val a = new Animal with Identity<br /> a.name = &quot;Kittie&quot;<br /> println(a.whoAmI)<br /> }<br />} // =&gt; Michael &lt; &gt; Kittie<br />
  • 21. Traits and Virtual Super: Inheritance Linearization<br />Page 18<br />abstract class Processor { def process() }<br />trait Compressor extends Processor { // trait only applicable to Processor subclass<br />abstract override def process() = { println(&quot;I am compressing&quot;); super.process }<br />}<br />trait Encryptor extends Processor { // only applicable to Processor subclass<br />abstract override def process() = { println(&quot;I am encrypting&quot;); super.process}<br />}<br />class SampleProcessor extends Processor { // subclass of Processor<br /> override def process() = println(&quot;I am a Sample Processor&quot;)<br />}<br />object traitsample2 {<br /> def main(args:Array[String]) = { // mixing in a trait to an object:<br />val proc1 = new SampleProcessor with Compressor with Encryptor<br />proc1.process// Encryptor.process=&gt;Compressor.process<br /> } // =&gt; SampleProcessor.process<br />}<br />Note: abstract override for a trait method means the actual subclass of Processor will provide a concrete implementation of that method!<br />
  • 22. Scala Basics: if Statements<br />If statements are expressions themselves, i.e. they have values<br />Page 19<br />import java.util._<br />if (1 + 1 == 3) <br />println(“strange world”) <br />else {<br />println(“everything’s ok”)<br />}<br />val res = if ((new Random().nextInt(6) + 1) == 6) <br /> &quot;You win!&quot; <br /> else <br /> &quot;You lose!&quot;<br />
  • 23. Scala Basics: for Comprehensions (1)<br />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:<br />You can specify filters for the collection elements<br />Page 20<br />val aList = List(1,2,3,4,5,6)<br />for (i &lt;- aList) println(i) // =&gt; 1 &lt; &gt; 2 ...<br />val dogs = Set(&quot;Lassie&quot;, &quot;Lucy&quot;, &quot;Rex&quot;, &quot;Prince&quot;);<br />for (a &lt;- dogs if a.contains(&quot;L&quot;)) println(a)<br />// =&gt; “Lassie” &lt; &gt; “Lucy”<br />
  • 24. Scala Basics: for Comprehensions (2)<br />Yield allows to create new collections in a for comprehension:<br />You can specify filters for the collection elements<br />Page 21<br />var newSet = for { <br /> a &lt;- dogs <br /> if a.startsWith(&quot;L&quot;)<br /> } yield a<br />println(newSet) // Set(Lassie, Lucy)<br />for { <br /> i &lt;- List(1,2,3,4,5,6)<br /> j = i * 2 // new variable j defined<br />} println(j) // =&gt; 2 &lt; &gt; 4 &lt; &gt; 6 ...<br />
  • 25. Scala Basics: Other loops<br />Scala supports while and do-while loops<br />But generator expressions such as (1 to 6) incl. 6 or (1 until 6) excl. 6 together with for make this much easier<br />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<br />Page 22<br />var i = 1<br />while (i &lt;= 6) {<br /> println(i)<br /> i += 1<br />} // = 1 &lt; &gt; 2 &lt; &gt; 3 ...<br /> for (i &lt;- 1 to 6) println(i)<br />
  • 26. Scala Basics: Exception handling<br />try-catch-finally available in Scala but throws isn‘t<br />catching checked exceptions is optional!<br />catch-order important as in Java, C++ or C#<br />Page 23<br />def temperature(f: Double) {<br /> if (f &lt; 0) throw new IllegalArgumentException()<br />}<br />try {<br /> println(&quot;acquiring resources&quot;)<br /> temperature(-5)<br />}<br />catch {<br /> case ex: IllegalArgumentException =&gt; println(&quot;temperatur &lt; 0!&quot;)<br /> case _ =&gt; println(&quot;unexpected problem&quot;)<br />}<br />finally {<br /> println(&quot;releasing resources&quot;)<br />} <br />
  • 27. Inner Classes<br />You may define inner classes as in Java<br />Special notation (&lt;name&gt; =&gt;) for referring to outer class this from an inner class: you might also use &lt;outerclass&gt;.this instead<br />Page 24<br />class Element (val id: String){ elem =&gt;<br />class Properties { // inner class<br />type KV = Tuple2[String, Any]<br /> var props: List[KV] = Nil<br /> def add(entry: KV) { props = entry :: props }<br /> override def toString = {<br /> var s: String = &quot;&quot;<br /> for (p &lt;- properties.props) s = s + p +&quot; &quot;<br /> s<br /> }<br />}<br /> override def toString = &quot;ID = &quot; + id + &quot; &quot; + properties<br /> val properties = new Properties <br />}<br />object InnerClassDemo extends Application {<br /> val e = new Element(&quot;Window&quot;)<br /> e.properties.add(&quot;Color&quot;, &quot;Red&quot;)<br /> e.properties.add(&quot;Version&quot;, 42)<br /> println(e.toString)<br />}<br />
  • 28. Imports and Packages<br />We can partition Scala definitions into packages:<br />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<br />Importing packages works via import statements – almost like in Java<br />Packages scala, java.lang, scala.Predefare automatically imported<br />Page 25<br />package MyPackage1 {<br /> class Person(val name: String)<br /> class Animal(val name: String)<br />}<br />import MyPackage1._<br />object PacDemo extends Application {<br /> val person = new Person(&quot;Michael&quot;)<br /> println(person name)<br />}<br /><ul><li> import p._ all members of p (this is analogous </li></ul> to import p.* in Java). <br /><ul><li> import p.x the member x of p.
  • 29. import p.{x =&gt; 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.</li></li></ul><li>Advanced Types: Lists<br />Collection Type: List<br />Page 26<br />object ListDemo {<br /> def main(args:Array[String]) {<br /> val l1 : List[Int] = Nil // empty List<br /> val l2 = List[Int](1,2,3,4,5) // list with 5 elements<br /> val l3 = 0 :: l2 // add 0 to the list<br /> val l4 = List[Int](0,1,2) ::: List[Int](3,4,5) // concat 2 lists<br /> println(&quot;Top Element: &quot; + l4.head) // =&gt; 0<br /> println(&quot;Rest of list: &quot; + l4.tail) // =&gt; List(1,2,3,4,5)<br /> println(&quot;Last Element: &quot; + l4.last) // =&gt; 5<br />l4.foreach { i =&gt; println(i) } // =&gt; 1 &lt; &gt; 2 &lt; &gt; 3 ...<br /> }<br />}<br />Foreach traverses a list and passes each element found to the closure passed as argument<br />
  • 32. Advanced Types: Sets<br />Collection Type: Set<br />Page 27<br />object SetDemo {<br /> def main(args:Array[String]) {<br />val s1 = Set[Int](1,2,3,4,5) // we could also use = Set(1,2,3,4,5)<br />val s2 = Set[Int](2,3,5,7)<br />println(s2.contains(3)) // =&gt; true<br />val s3 = s1 ++ s2 // union<br />println(s3) // =&gt; Set(5,7,3,1,4,2)<br />vals4 = s1 &amp; s2 // intersection: in earlier versions **<br />println(s4) // Set(5,3,2) <br /> }<br />}<br />
  • 33. Advanced Types: Maps<br />Collection Type: Map<br />Page 28<br />object MapDemo {<br /> def main(args:Array[String]) {<br />val m1 = Map[Int, String](1 -&gt; &quot;Scala&quot;, 2-&gt;&quot;Java&quot;, 3-&gt;&quot;Clojure&quot;)<br />valm2 = m1 + (4 -&gt; &quot;C#&quot;) // add entry<br />println(m2 + &quot; has size &quot; + m2.size) <br /> //=&gt; Map(1-&gt;Scala,…) has size 4<br />println(m1(1)) // =&gt; Scala<br />val m3 = m2 filter { element =&gt; val (key, value) = element<br /> (value contains &quot;a&quot;) } <br />println(m3) // =&gt; Map(1-&gt;Scala, w-&gt;Java)<br /> }<br />}<br />
  • 34. Advanced Types: Options<br />object DayOfWeek extends Enumeration {<br /> val Monday = Value(&quot;Monday&quot;) //argument optional <br /> val Sunday = Value(&quot;Sunday&quot;) //argument optional <br />}<br />import DayOfWeek._ <br />object OptionDemo {<br /> def whatIDo(day: DayOfWeek.Value) : Option[String] = <br /> {<br /> day match {<br /> case Monday =&gt; Some(&quot;Working hard&quot;)<br /> case Sunday =&gt; None<br /> }<br /> }<br /> def main(args:Array[String]) {<br /> println(whatIDo(DayOfWeek.Monday)) <br /> println(whatIDo(DayOfWeek.Sunday)) <br /> } //=&gt; Some(„Working Hard“) &lt; &gt; None<br />}<br />The Option type helps dealing with optional values<br />For instance, a search operation might return a result or nothing<br />We are also introducing Enumerationtypes<br />Page 29<br />
  • 35. Advanced Types: Regular Expressions<br />Type: Regex introduces well-known regular expressions<br />Page 30<br />With this syntax strings remain formatted as specified and escape sequences are not required<br />object RegDemo {<br /> def main(args:Array[String]) {<br />val pattern = &quot;&quot;&quot;dd.dd.dddd&quot;&quot;&quot;.r<br />val sentence = “X was born on 01.01.2000 ?&quot;<br />println (pattern findFirstIn sentence) // =&gt; Some(01.01.2000)<br /> }<br />}<br />Note: the „r“ in “““&lt;string&gt;“““.r means: regular expression<br />
  • 36. Advanced Types: Tuples<br />Tuples combine fixed number of Elements of various types<br />Thus, you are freed from creating heavy-weight classes for simple aggregates<br />Page 31<br />println( (1, &quot;Douglas Adams&quot;, true) )<br />def goodBook = {<br />(&quot;Douglas Adams&quot;, 42, &quot;Hitchhiker&apos;s Guide&quot;)<br />} <br />println ( goodBook._3 ) // get third element<br />// =&gt; (1, Douglas Adams, true)<br />// =&gt; Hitchhiker‘s Guide<br />
  • 37. Advanced Types: Arrays<br />Arrays hold sequences of elements<br />Access very efficient<br />Page 32<br />val a1 = new Array[Int](5) // initialized with zeros <br />val a2 = Array(1,2,3,4,5) // initialized with 1,2,3,4,5<br />println( a2(1) ) // =&gt; 2<br />a2(1) = 1 // =&gt; Array (1,1,3,4,5)<br />Note:<br />In Scala the assignment operator = does not return a reference to the left variable (e.g., in a = b).<br />Thus, the following is allowed in Java but not in Scala: a = b = c <br />
  • 38. Smooth Operator<br />In Scala operator symbols are just plain method names <br />For instance 1 + 2 stands for 1.+(2)<br />Precedence rules:<br />All letters<br />|<br />^<br />&amp;<br />&lt; &gt;<br />= !<br />:<br />+ -<br />* / %<br />Page 33<br />class Complex(val re:Double, val im:Double) {<br />def +(that: Complex) : Complex = {<br /> new Complex(this.re + that.re, <br /> this.im + that.im)<br /> }<br /> override def toString() : String = {<br /> re + (if (im &lt; 0) &quot;&quot; else &quot;+&quot;) + im +&quot;i&quot;<br /> }<br />}<br />object Operators {<br /> def main(args: Array[String]) {<br /> val c1 = new Complex(1.0, 1.0)<br /> val c2 = new Complex(2.0, 1.0)<br /> println(c1+c2)<br /> }<br />} // =&gt; (3.0+2.0i)<br />
  • 39. Conversions<br />Implicit converters allow Scala to automatically convert data types<br />Suppose, you‘d like to introduce a mathematical notatation such as 10! <br />Using implicit type converters you can easily achieve this<br />Page 34<br />object Factorial {<br /> def fac(n: Int): BigInt =<br /> if (n == 0) 1 else fac(n-1) * n<br /> class Factorizer(n: Int) {<br />def ! = fac(n)<br /> }<br />implicit def int2fac(n: Int) = new Factorizer(n)<br />}<br />import Factorial._<br />object ConvDemo extends Application {<br />println(&quot;8! = &quot; + (8!)) // 8 will be implicitly converted<br />} // =&gt; 40320<br />
  • 40. Parameterized Types in Scala<br />Classes, Traits, Functions may be parameterized with types<br />In contrast to Java no wildcards permitted – parameter types must have names<br />Variance specification allow to specify covariance and contravariance<br />Page 35<br />trait MyTrait[S,T] {<br /> def print(s:S, t:T) : String = &quot;(&quot; + s + &quot;,&quot; + t + &quot;)&quot;<br />}<br />class MyPair[S,T] (val s : S, val t : T) <br />extends MyTrait [S,T] {<br /> override def toString() : String = print(s,t) <br />}<br />object Generics {<br /> def main(args: Array[String]) {<br /> val m = new MyPair[Int,Int](1,1)<br /> printf(m.toString())<br /> }<br />} // =&gt; (1,1)<br />
  • 41. Small Detour to Variance and Covariance / Type Bounds<br />If X[T] is a parameterized type and T an immutable type:<br />X[T] is covariant in T if: S subTypeOf T =&gt; X[S] subTypeOf X[T]<br />X[T] is contravariant in T if: S subTypeOf T =&gt; X[S] superTypeOf X[T]<br />In Scala covariance is expressed as X[+T] and contravariance with X[-T]<br />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<br />Example List[+T]: Covariance means a List[Int] can be assigned to a List[Any] because Int is subtype of Any<br />Upper/Lower Bounds may be specified:<br />In the following example D must be supertype of S:<br /> def copy[S, D&gt;:S](src: Array[S], dst: Array[D]) = { ...<br />Page 36<br />
  • 42. Functional Aspects: Functions and Closures<br />In Scala Functions are First-Class Citizens<br />They can be <br />passed as arguments<br />assigned to variables: val closure={i:Int =&gt; i+42}<br />Nested functions are also supported<br />Page 37<br />object scalafunctions {<br /> def add(left:Int,right:Int, code:Int=&gt;Int)=<br /> {<br />var res = 0<br /> for (i&lt;-left to right) res += code(i)<br /> res<br /> }<br /> def main(args: Array[String]) {<br />println(add(0,10, i =&gt; i))<br />println(add(10,20, i =&gt; i % 2 ))<br /> }<br />}<br />=&gt;<br />55<br />5<br />
  • 43. Functional Aspects: Call-by-Name<br />If a parameterless closure is passed as an argument to a function, Scala will evaluate the argument when the argument is actually used<br />This is in contrast to call-by-value arguments<br />A similar effect can be achieved using lazy (value) evaluation: <br />lazy val = &lt;expr&gt; <br />Page 38<br />import java.util._<br />object CbNDemo {<br />def fun(v: =&gt; Int) : Int = v <br /> // v is a Call-by-Name Parameter<br />def v() : Int = new Random().nextInt(1000)<br /> def main(args:Array[String]) {<br /> println( fun(v) )<br /> println( fun(v) ) <br /> }<br />} // =&gt; 123 &lt; &gt; 243<br />
  • 44. Functional Aspects: Currying (1)<br />Currying means to transform a function with multiple arguments to a nested call of functions with one (or more) argument(s)<br />def fun(i:Int)(j:Int) {}<br /> (Int)=&gt;(Int)=&gt;Unit=&lt;function1&gt;<br />Page 39<br />object scalafunctions {<br /> def fun1(i:Int, j:Int) : Int = i + j<br />def fun2(i:Int)(j:Int) : Int = i + j <br /> def main(args: Array[String]) {<br /> println(fun1(2,3))<br /> println(fun2(2){3})<br /> println(fun2{2}{3} )<br /> }<br />} // =&gt; 5 5 5<br />
  • 45. Functional Aspects: Currying (2)<br />Currying helps increase readability<br />Take foldleft as an example<br />Page 40<br />FoldLeft Operator<br />val x = (0 /: (1 to 10)) { (sum, elem) =&gt; sum + elem } // 55 <br />Carryover value for next iteration<br />Function arguments<br />Carryover value<br />Collection<br />For each iteration, foldleft passes the carry over value and the current collection element. We need to provide the operation to be applied<br />This is collection which we iterate over<br />This is the value that is updated in each iteration<br />Think how this would be implemented in Java!<br />
  • 46. Positional Parameters<br />If you use a parameter only once, you can use positional notation of parameters with _ (underscore) instead<br />Page 41<br />object scalafunctions {<br /> def main(args:Array[String]) {<br /> val seq= (1 to 10)<br /> println( (0 /: seq) { (sum, elem) =&gt; sum + elem } )<br /> println( (0 /: seq) { _ + _ } )<br /> } <br />}<br />
  • 47. Using the features we can build new DSLs and additional features easily<br />The following loop-unless example is from the Scala tutorial <br />Page 42<br />object TargetTest2 extends Application {<br />def loop(body: =&gt; Unit): LoopUnlessCond =<br /> new LoopUnlessCond(body)<br />protected class LoopUnlessCond(body: =&gt; Unit) {<br /> def unless(cond: =&gt; Boolean) {<br /> body<br /> if (!cond) unless(cond)<br /> }<br /> }<br /> var i = 10 <br /> loop {<br /> println(&quot;i = &quot; + i)<br /> i -= 1<br /> } unless (i == 0)<br />}<br />We are calling loop<br />with this body ...<br />and invoking unless<br />on the result<br />
  • 48. Functional Aspect: Partially Applied Functions<br />If you only provide a subset of arguments to a function call, you actually retrieve a partially defined function<br />Only the passed arguments are bound, all others are not<br />In a call to a partially applied function you need to pass the unbound arguments<br />All this is useful to leverage the DRY principle when passing the same arguments again and again<br />Page 43<br />object scalafunctions {<br /> def fun(a : Int, b : Int, c:Int) = a+b+c<br /> def main(args: Array[String]) {<br />val partialFun = fun(1,2,_:Int)<br /> println( partialFun(3) ) // 6<br /> println( partialFun(4) ) // 7<br /> }<br />}<br />
  • 49. Functions Are Objects<br /> Function: S =&gt; T<br /> trait Function1[-S,+T] {<br /> def apply(x:S):T<br /> }<br />Example: <br /> (x: Int) =&gt; x * 2<br />-&gt; new Function1[Int,Int] {<br /> def apply(X:Int):Int = x * 2<br /> }<br />In Scala all function values are objects<br />Basically, each function is identical to a class with an apply method<br />Thus, you can even derive subclasses from functions<br />Array is an example for this: <br />class Array [T] (length: Int ) <br />extends (Int =&gt; T) {<br />def length: Int = ...<br />Page 44<br />
  • 50. Functional Aspects: Pattern Matching<br />Pattern matching allows to make a pragmatic choice between various options<br />Page 45<br />valaNumber = new Random().nextInt(6) + 1;<br />aNumbermatch {<br />case 6 =&gt; println(&quot;You got a 6&quot;)<br />case 1 =&gt; println(&quot;You got a 1&quot;);<br />caseotherNumber =&gt; println(&quot;It is a &quot; + otherNumber)<br />} <br />
  • 51. Functional Aspects: Matching on Types<br />It is also possible to differentiate by type:<br />Page 46<br />object TypeCase {<br /> def matcher(a: Any) {<br />a match {<br /> case i : Int if (i == 42) =&gt; println(&quot;42&quot;)<br /> case j : Int =&gt; println(&quot;Another int&quot;)<br /> case s : String =&gt; println(s)<br /> case _ =&gt; println(&quot;Something else&quot;)<br /> }<br /> }<br /> def main(args: Array[String]) {<br /> matcher(42)<br /> matcher(1)<br /> matcher(&quot;OOP&quot;)<br /> matcher(1.3) <br /> }<br />} // =&gt; 41 &lt; &gt; 1 &lt; &gt; OOP &lt; &gt; Something else<br />
  • 52. Functional Aspects: Matching on Lists<br />Lists can be easily used with Pattern Matching:<br />Page 47<br />object ListCase {<br /> def matcher(l: List[Int]) {<br />l match {<br /> case List(1,2,3,5,7) =&gt; println(&quot;Primes&quot;)<br /> case List(_,_,_3,_) =&gt; println(&quot;3 on 3&quot;);<br /> case 1::rest =&gt; println(&quot;List with starting 1&quot;);<br /> case List(_*) =&gt; println(&quot;Other List&quot;);<br /> }<br /> }<br /> def main(args: Array[String]) {<br /> matcher(List(1,2,3,5,7))<br /> matcher(List(5,4,3,2))<br /> matcher(List(1,4,5,6,7,8));<br /> matcher(List(42))<br /> }<br />} =&gt; Primes &lt; &gt; 3 on 3 &lt; &gt; List with starting 1 &lt; &gt; Other List<br />
  • 53. Functional Aspects: Matching on Tuples<br />So do Tuples:<br />Page 48<br />object TupleCase {<br /> def matcher(t : Tuple2[String,String]) {<br />t match {<br /> case (&quot;OOP&quot;,s) =&gt; println(&quot;OOP &quot; + s)<br /> case (&quot;Scala&quot;, s) =&gt; println(&quot;Scala &quot; + s)<br /> case _ =&gt; println(&quot;Other Tuple&quot;)<br /> }<br /> }<br /> def main(args: Array[String]) {<br /> matcher(&quot;OOP&quot;, &quot;2010&quot;)<br /> matcher(&quot;Scala&quot;, &quot;rocks&quot;);<br /> matcher(&quot;A&quot;,&quot;B&quot;)<br /> }<br />} =&gt; OOP 2010 &lt; &gt; Scala rocks &gt;cr&gt; Other Tuple<br />
  • 54. Functional Aspects: Matching on Case Classes<br />Case Classes are classes for which the compiler generates additional functionality to enable pattern matching, e.g., an apply() method:<br />Page 49<br />sealed abstract class Shape // sealed =&gt; subclasses only in this source file<br />case class Circle(val center: Point, val radius: Double) extends Shape<br />case class Line(val pt1: Point, val pt2: Point) extends Shape<br />case class Point (val x:Double, val y:Double){<br /> override def toString() = &quot;(&quot; + x +&quot;,&quot; + y + &quot;)&quot; }<br />object CaseClasses {<br /> def matcher(s : Shape) {<br />s match {<br /> case Circle(c, r) =&gt; println(“Circle“ : + c + “ “ + r)<br /> case Line(p1, p2) =&gt; println(&quot;Line &quot; + p1 + &quot; : &quot; + p2) <br /> case _ =&gt; println(&quot;Unknown shape&quot;)<br /> }<br /> }<br /> def main(args: Array[String]) {<br /> matcher(Circle(Point(1.0, 1.0), 2.0))<br /> matcher(Line(Point(1.0, 1.0), Point(2.0, 2.0)))<br /> }<br />}<br />
  • 55. Functional Aspect: Extractors<br />Extractors are objects with an unapply method used to match a value and partition it into constituents – an optional apply is used for synthesis<br />Page 50<br />object EMail {<br /> def apply(prefix: String, domain: String) = prefix + &quot;@&quot; + domain<br />def unapply(s: String): Option[(String,String)] = {<br /> val parts = s split &quot;@&quot;<br /> if (parts.length == 2) Some(parts(0), parts(1)) else None<br /> } <br />}<br />object scalafunctions {<br /> def main(args:Array[String]) {<br /> val s = &quot;michael.stal@siemens.com&quot;<br /> s match { <br /> case EMail(user, domain) =&gt; println(user + &quot; AT &quot; + domain)<br /> case _ =&gt; println(&quot;Invalid e-mail&quot;)<br /> }<br /> } <br />}<br />
  • 56. Partial Functions <br />Partial Functions are not defined for all domain values<br />Can be asked with isDefinedAt whether a domain value is accepted<br />Example: Blocks of Pattern Matching Cases<br />Page 51<br />trait PartialFunction[-D, +T] <br />extends (D =&gt; T) {<br /> def isDefinedAt(x: D): Boolean<br />}<br />
  • 57. Actors<br />Actors have been introduced in the 1970s:<br />the Actor model is a mathematical model of concurrent computationthat treats &quot;actors&quot; 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]<br />Page 52<br />Also available in Erlang, Axum, Io, Clojure<br />Provided as library implementation in Scala (demonstrating Scala‘s capability of providing internal DSLs)<br />
  • 58. Actor Classes<br />Class Actor requires to override act() which is the functionality executed by a thread<br />You may also instantiate anonymous actors in a much more convenient way:<br />Page 53<br />import scala.actors.Actor<br />class VolcanextendsActor {<br />def act() {<br />println(“thinking ...&quot;)<br /> }<br />}<br />object SpockRunner {<br /> def main(args:Array[String]) = {<br />valspock = new Volcan<br />spock start<br /> }<br />}<br />import scala.actors.Actor<br />import Actor._<br />object SpockRunner {<br /> def main(args:Array[String]) = {<br />val spock = actor {<br /> println(&quot;thinking ...&quot;)<br /> }<br /> }<br />}<br />
  • 59. Actors that communicate<br />An actor is useless unless it cooperates with other actors<br />Actors communicate via messages<br />In Scala‘s actor library messages are processed in FIFO order<br />Every actor owns an inbound and an outbound mailbox<br />Page 54<br />
  • 60. Communicating Actors - Example<br />Page 55<br />!<br />Note: react &amp; receive have cousins with timeout arguments: receiveWithin and reactWithin<br />import scala.actors._<br />import Actor._<br />object Calculator extends Actor {<br /> def fib(n: Int) : Int = { require(n &gt;= 0) // this is a precondition <br />if (n &lt;= 1) n else fib(n-2) + fib(n-1) }<br /> def act() {<br />loop {<br /> react { // or receive if thread must preserve call-stack<br /> case i:Int =&gt; actor {println(&quot;Fibonacci of &quot;+i+&quot; is &quot;+fib(i))}<br /> case s:String if (s == „exit&quot;) =&gt; {println(„exit!&quot;); exit}<br /> case _ =&gt; println(&quot;received unknown message&quot;) <br /> }<br /> }<br /> }<br />}<br />object ActorDemo extends Application {<br /> Calculator.start // start Actor<br /> for (i &lt;- 0 to 30) Calculator ! i // here we send a msg to the actor<br />Calculator ! &quot;exit&quot;<br />}<br />
  • 61. Processing XML in Scala<br />Scala can directly handle XML<br />With package scala.xml we can read, parse, create and store XML documents<br />XPath like query syntax<br />Page 56<br />import scala.xml._ // in our example not required<br />object XMLDemo extends Application {<br /> val x : scala.xml.Elem = <br />&lt;conferences&gt;<br /> &lt;conference name=&quot;OOP&quot;&gt; &lt;year&gt; 2010 &lt;/year&gt; &lt;/conference&gt;<br /> &lt;conference name=&quot;SET&quot;&gt; &lt;year&gt; 2010 &lt;/year&gt; &lt;/conference&gt;<br /> &lt;/conferences&gt;<br /> var conferenceNodes = x &quot;conference„ // get all conference nodes<br /> for (c &lt;- conferenceNodes) println( c&quot;@name“ ) // get attribute<br />} // =&gt; OOP &lt; &gt; SET<br />
  • 62. Accessing the Web with Scala<br />You may use a mixture of Java and Scala code to access the Web<br />Suppose, you‘d like to read a Web Page<br />Here is an example how this might work<br />Page 57<br />import java.net._<br />object WebDemo {<br /> def main(args: Array[String]) {<br /> require(args.length == 1)<br />// we assume an URL was passed at the<br /> // command line:<br />val url = new URL(args(0)) // make URL<br />// read web page stream and convert<br /> // result to a string:<br /> val page = <br />io.Source.fromURL(url).mkString<br /> println(page) // display result <br /> }<br />}<br />
  • 63. Scala Installation &amp; Use<br />Download distribution from http://www.scala-lang.org<br />You may use<br />Scala Compilers: scalac and fsc<br />Eclipse, JetBrains, NetBeans Plug-In<br />REPL (Read-Eval-Print-Loop) shell: scala<br />I have tested these on Windows {XP, Vista} as well as Mac OS X (Snow Leopard)<br />Or a Web site for evaluating Scala scripts: http://www.simplyscala.com/<br />If you are interested in a Web Framework based on Scala use Lift 1.0: http://liftweb.net/<br />Page 58<br />
  • 64. Summary<br />Scala combines the best of two worlds: OO and Functional Programming<br />It runs on the JVM and offers Java interoperability<br />Actor library helps dealing with complexity of concurrent programming <br />Scala programs are compact and concise =&gt; big productivity boost possible<br />Upcoming v2.8 will offer additional benefits such as named &amp; default arguments<br />Scala is no island - many further tools and frameworks (e.g., Lift) available<br />Coding with Scala is fun - Try it yourself!<br />Page 59<br />
  • 65. Books: My Recommendations<br />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!<br />V. Subramanian: Programming Scala: Tackle Multi-Core Complexity on the Java Virtual Machine (Pragmatic Programmers) (Paperback), Pragmatic Bookshelf (July 15, 2009) <br />D. Wempler, A. Paine: Programming Scala: Scalability = Functional Programming + Objects (Animal Guide) (Paperback), O&apos;Reilly Media; 1st edition (September 25, 2009)<br />A lot of additional books available in the meantime. <br />Page 60<br />

×