Date post: | 15-Jan-2015 |
Category: |
Technology |
Upload: | christian-baranowski |
View: | 998 times |
Download: | 6 times |
Einführung in ScalaSDC 2011 - Seitenbau Konstanz
Christian BaranowskiDennis Braunsdorf
Was ist Scala?
Scala a Scalable Language
Scala Bazaar
Scala = Bazaar
Java = Cathedral
“The Cathedral and the Bazaar” - Eric S. Raymond
Warum Scala?
Scala ist objekt-orientiert
Everything is a Object
Scala ist funktional
Scala ist statisch typisiert
Scala Basics
Variablen
var msg = "Hello SDC!"// Java CodeString msg = "Hello World";
val msg = "Hello SDC!“
// Java Codefinal String msg = "Hello World";
var msg = "Hello SDC!"// Java CodeString msg = "Hello World";
val msg = "Hello SDC!“
// Java Codefinal String msg = "Hello World";
Funktionen
def max(x : Int, y : Int) : Int = { if(x > y) { return x; } else { return y; }}
def max(x : Int, y : Int) : Int = { if(x > y) { return x; } else { return y; }}
Funktionen
def max(x : Int, y : Int) : Int = { if(x > y) { x } else { y }}
def max(x : Int, y : Int) : Int = { if(x > y) { x } else { y }}
Funktionen
def max(x : Int, y : Int) : Int = { if(x > y) x else y}
def max(x : Int, y : Int) : Int = { if(x > y) x else y}
Funktionen
def max(x : Int, y : Int) = { if(x > y) x else y}
def max(x : Int, y : Int) = { if(x > y) x else y}
Procedure
def printer(msg : String) { ...}
def printer(msg : String) { ...}
Funktionen Composition and Scoping
def max(x : Int, y : Int) = { def xGreater() = { x > y } if(xGreater()) x else y}
def max(x : Int, y : Int) = { def xGreater() = { x > y } if(xGreater()) x else y}
Funktionen Composition and Scoping
def max(x : Int, y : Int) = { def xGreater() = { x > y } if(xGreater) x else y}
def max(x : Int, y : Int) = { def xGreater() = { x > y } if(xGreater) x else y}
Functions are objects
def oncePerSecond(callback: () => Unit) {while (true) { callback(); Thread sleep 1000 }
}
def timeFlies() {println("time flies like an arrow...")
}
oncePerSecond(timeFlies)
def oncePerSecond(callback: () => Unit) {while (true) { callback(); Thread sleep 1000 }
}
def timeFlies() {println("time flies like an arrow...")
}
oncePerSecond(timeFlies)
Anonymous Functions
def oncePerSecond(callback: () => Unit) {while (true) { callback(); Thread sleep 1000 }
}
oncePerSecond(() => println("time flies like an arrow..."))
def oncePerSecond(callback: () => Unit) {while (true) { callback(); Thread sleep 1000 }
}
oncePerSecond(() => println("time flies like an arrow..."))
Arrays
val names = new Array[String](2)names(0) = "Dennis"names(1) = "Christian"
val names = new Array[String](2)names(0) = "Dennis"names(1) = "Christian"
Arrays
val names = Array("Dennis", "Christian")val names = Array("Dennis", "Christian")
Arrays
val names = Array("Dennis", "Christian", true, 0, 1.5)
val names : Array[Any] = Array("Dennis", "Christian", true, 0, 1.5)
val names = Array("Dennis", "Christian", true, 0, 1.5)
val names : Array[Any] = Array("Dennis", "Christian", true, 0, 1.5)
Listen
val oneTwo = List(1, 2)
val threeFour = List(3, 4)
val oneTwoThreeFour = oneTwo ::: threeFour
val oneTwoThree = 1 :: 2 :: 3 :: Nil
val oneTwo = List(1, 2)
val threeFour = List(3, 4)
val oneTwoThreeFour = oneTwo ::: threeFour
val oneTwoThree = 1 :: 2 :: 3 :: Nil
Tuples
val dennis = (1, "Dennis")
val christian = (2, "Christian")
val dennis = ("Dennis", "Braunsdorf")
println(dennis._1)println(dennis._2)
val dennis = (1, "Dennis")
val christian = (2, "Christian")
val dennis = ("Dennis", "Braunsdorf")
println(dennis._1)println(dennis._2)
Sets
Sets
import scala.collection.mutable.HashSet
val jetSet = new HashSet[String]jetSet += "Lear"jetSet += ("Boeing", "Airbus")println(jetSet.contains("Cessna"))
import scala.collection.mutable.HashSet
val jetSet = new HashSet[String]jetSet += "Lear"jetSet += ("Boeing", "Airbus")println(jetSet.contains("Cessna"))
Sets
val jetSet = Set("AirBus")
jetSet: scala.collection.immutable.Set[java.lang.String]
val jetSet = Set("AirBus")
jetSet: scala.collection.immutable.Set[java.lang.String]
Maps
Maps
import scala.collection.mutable.HashMap
val treasureMap = new HashMap[Int, String]treasureMap += 1 -> "Go to island."treasureMap += 2 -> "Find big X on ground."treasureMap += 3 -> "Dig."println(treasureMap(2))
import scala.collection.mutable.HashMap
val treasureMap = new HashMap[Int, String]treasureMap += 1 -> "Go to island."treasureMap += 2 -> "Find big X on ground."treasureMap += 3 -> "Dig."println(treasureMap(2))
Maps
val treasureMap = Map( (1, "Go to island."), (2, "Find big X on ground."), (3, "Dig."))
val treasureMap = Map( (1, "Go to island."), (2, "Find big X on ground."), (3, "Dig."))
While Schleife
val names = Array("Dennis", "Christian")var i = 0while(i < names.length) { println(names(i)) i = i + 1}
val names = Array("Dennis", "Christian")var i = 0while(i < names.length) { println(names(i)) i = i + 1}
For Schleife
val names = Array("Dennis", "Christian")for(name <- names) println(name)
val names = Array("Dennis", "Christian")for(name <- names) println(name)
Foreach Collection
val names = Array("Dennis", "Christian")names.foreach(name => println(name))val names = Array("Dennis", "Christian")names.foreach(name => println(name))
Throw Exceptions
def max(x : Int, y : Int) : Int = { if(x < 0) throw new Exception("Negativ Int!") ...}
def max(x : Int, y : Int) : Int = { if(x < 0) throw new Exception("Negativ Int!") ...}
Catch Exceptions
try { ... } catch { case ioe: IOException
=> println("Fehler beim lesen auf dem Filesystem")
case e: Exception => println("Unbekannter Fehler")
}
try { ... } catch { case ioe: IOException
=> println("Fehler beim lesen auf dem Filesystem")
case e: Exception => println("Unbekannter Fehler")
}
Scala OOP Basics
Everything is a Object
Numbers are Objects
1 + 2 * 3 / x = (1).+(((2).*(3))./(x))1 + 2 * 3 / x = (1).+(((2).*(3))./(x))
Objekte
object DemoService { def print(msg : String) { println(msg) } }
DemoService.print("Hello World")
object DemoService { def print(msg : String) { println(msg) } }
DemoService.print("Hello World")
Klassen
class Complex(real: Double, imaginary: Double) {def re() = realdef im() = imaginary
}
class Complex(real: Double, imaginary: Double) {def re() = realdef im() = imaginary
}
Klassen
class Complex(real: Double, imaginary: Double) {def re = realdef im = imaginary
}
class Complex(real: Double, imaginary: Double) {def re = realdef im = imaginary
}
Abstrakte Klassen
abstract class Complex(real: Double, imaginary: Double) {
abstract def re()def im = imaginary
}
abstract class Complex(real: Double, imaginary: Double) {
abstract def re()def im = imaginary
}
Klassen
protected class Complex(real: Double, imaginary: Double) {
private def re() = realprotected def im() = imaginary
}
protected class Complex(real: Double, imaginary: Double) {
private def re() = realprotected def im() = imaginary
}
Auxiliary Constructors
class Complex(real: Double, imaginary: Double) {
def this() = this(0,0)
def re() = realdef im() = imaginary
}
class Complex(real: Double, imaginary: Double) {
def this() = this(0,0)
def re() = realdef im() = imaginary
}
Packages und Imports
package demo
import javax._
import scala.collection.mutable.HashMap
package demo
import javax._
import scala.collection.mutable.HashMap
Scala Live DemoGetting Started ….
Scala OOP Teil 2
Traits
trait Ord {def < (that: Any): Booleandef <=(that: Any): Boolean
= (this < that) || (this == that)def > (that: Any): Boolean = !(this <= that)def >=(that: Any): Boolean = !(this < that)
}
trait Service
class MyOrd extends Ord with Service { def < (that: Any): Boolean = false }
trait Ord {def < (that: Any): Booleandef <=(that: Any): Boolean
= (this < that) || (this == that)def > (that: Any): Boolean = !(this <= that)def >=(that: Any): Boolean = !(this < that)
}
trait Service
class MyOrd extends Ord with Service { def < (that: Any): Boolean = false }
Operators + * - /
class Demo { def + (x : Int) = 1 + x}
var o1 = new MyOrdprintln(o1 + 1)
class Demo { def + (x : Int) = 1 + x}
var o1 = new MyOrdprintln(o1 + 1)
Methoden Overloading
class Demo { def + (x : Int) = 1 + x def + (x : Demo) = 1 + 1}
class Demo { def + (x : Int) = 1 + x def + (x : Demo) = 1 + 1}
Methoden Überschreiben
class Complex(real: Double, imaginary: Double) {
def re = realdef im = imaginaryoverride def toString() =
"" + re + (if (im < 0) "" else "+") + im + "i„
}
class Complex(real: Double, imaginary: Double) {
def re = realdef im = imaginaryoverride def toString() =
"" + re + (if (im < 0) "" else "+") + im + "i„
}
Case Klassen
abstract class Treecase class Sum(l: Tree, r: Tree) extends Treecase class Var(n: String) extends Treecase class Const(v: Int) extends Tree
abstract class Treecase class Sum(l: Tree, r: Tree) extends Treecase class Var(n: String) extends Treecase class Const(v: Int) extends Tree
Pattern Matching
def eval(t: Tree, env: Environment): Int = t match {case Sum(l, r) => eval(l, env) + eval(r, env)case Var(n) => env(n)case Const(v) => v
}
def derive(t: Tree, v: String): Tree = t match {case Sum(l, r) => Sum(derive(l, v), derive(r, v))case Var(n) if (v == n) => Const(1)case _ => Const(0)
}
val exp: Tree = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y")))val env: Environment = { case "x" => 5 case "y" => 7 }println("Expression: " + exp)println("Evaluation with x=5, y=7: " + eval(exp, env))println("Derivative relative to x:\n " + derive(exp, "x"))println("Derivative relative to y:\n " + derive(exp, "y"))
def eval(t: Tree, env: Environment): Int = t match {case Sum(l, r) => eval(l, env) + eval(r, env)case Var(n) => env(n)case Const(v) => v
}
def derive(t: Tree, v: String): Tree = t match {case Sum(l, r) => Sum(derive(l, v), derive(r, v))case Var(n) if (v == n) => Const(1)case _ => Const(0)
}
val exp: Tree = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y")))val env: Environment = { case "x" => 5 case "y" => 7 }println("Expression: " + exp)println("Evaluation with x=5, y=7: " + eval(exp, env))println("Derivative relative to x:\n " + derive(exp, "x"))println("Derivative relative to y:\n " + derive(exp, "y"))
Advanced Features
For-Comprehensions
for (p <- persons if p.age > 20) yield p.name
def queens(n: Int): List[List[Int]] = { def placeQueens(k: Int): List[List[Int]] = if (k == 0) List(List()) else for { queens <- placeQueens(k - 1) column <- List.range(1, n + 1) if isSafe(column, queens, 1) } yield column :: queens placeQueens(n)}
def isSafe(col: Int, queens: List[Int], delta: Int): Boolean
for (b <- books; a <- b.authors if a startsWith "Ullman") yield b.title
for (p <- persons if p.age > 20) yield p.name
def queens(n: Int): List[List[Int]] = { def placeQueens(k: Int): List[List[Int]] = if (k == 0) List(List()) else for { queens <- placeQueens(k - 1) column <- List.range(1, n + 1) if isSafe(column, queens, 1) } yield column :: queens placeQueens(n)}
def isSafe(col: Int, queens: List[Int], delta: Int): Boolean
for (b <- books; a <- b.authors if a startsWith "Ullman") yield b.title
Genericity
class Reference[T] { private var contents: T = _ def set(value: T) { contents = value } def get: T = contents}
object IntegerReference { def main(args: Array[String]) { val cell = new Reference[Int] cell.set(13) println("Reference contains the half of "
+ (cell.get * 2)) }}
class Reference[T] { private var contents: T = _ def set(value: T) { contents = value } def get: T = contents}
object IntegerReference { def main(args: Array[String]) { val cell = new Reference[Int] cell.set(13) println("Reference contains the half of "
+ (cell.get * 2)) }}
Generic Stack
abstract class Stack[A] { def push(x: A): Stack[A] = new NonEmptyStack[A](x, this) def isEmpty: Boolean def top: A def pop: Stack[A]}class EmptyStack[A] extends Stack[A] { def isEmpty = true def top = error("EmptyStack.top") def pop = error("EmptyStack.pop")}class NonEmptyStack[A](elem: A, rest: Stack[A]) extends Stack[A] { def isEmpty = false def top = elem def pop = rest}
abstract class Stack[A] { def push(x: A): Stack[A] = new NonEmptyStack[A](x, this) def isEmpty: Boolean def top: A def pop: Stack[A]}class EmptyStack[A] extends Stack[A] { def isEmpty = true def top = error("EmptyStack.top") def pop = error("EmptyStack.pop")}class NonEmptyStack[A](elem: A, rest: Stack[A]) extends Stack[A] { def isEmpty = false def top = elem def pop = rest}
Lazy Values
case class Employee(id: Int, name: String, managerId: Int) { lazy val manager: Employee = Db.get(managerId) lazy val team: List[Employee] = Db.team(id)}
case class Employee(id: Int, name: String, managerId: Int) { lazy val manager: Employee = Db.get(managerId) lazy val team: List[Employee] = Db.team(id)}
Implicit Parameters
implicit object stringMonoid extends Monoid[String] { def add(x: String, y: String): String = x.concat(y) def unit: String = ""}
implicit object intMonoid extends Monoid[Int] { def add(x: Int, y: Int): Int = x + y def unit: Int = 0}
implicit object stringMonoid extends Monoid[String] { def add(x: String, y: String): String = x.concat(y) def unit: String = ""}
implicit object intMonoid extends Monoid[Int] { def add(x: Int, y: Int): Int = x + y def unit: Int = 0}
Implicit Conversions
implicit def int2ordered(x: Int): Ordered[Int] = new Ordered[Int] { def compare(y: Int): Int = if (x < y) -1 else if (x > y) 1 else 0}
implicit def int2ordered(x: Int): Ordered[Int] = new Ordered[Int] { def compare(y: Int): Int = if (x < y) -1 else if (x > y) 1 else 0}
Annotations
@fieldclass BeanProperty extends annotation.StaticAnnotation@fieldclass BeanProperty extends annotation.StaticAnnotation
Scala Java Integration// Java public class MainJava { public static void main(String[] args) {
Point point = new Point();point.name();
}}
// Scalaclass Point(x : Int, y : Int) { var name = "Bin ein Point" def this() = this(0, 0) override def toString = name + " : x=" + x + " : y=" + y
}
Package Objects
package object demo { implicit def toPoint(name: String) = new Point}
package object demo { implicit def toPoint(name: String) = new Point}
Scala in Action
Java Beans mit Scala
class PersonBean {
@scala.reflect.BeanProperty var name : String = "" }
JUnit Tests with Scalaimport org.junit._import org.junit.Assert._;
class MaxTest {
var max : MathUtils = null; @Before def setup(){ max = new MathUtils } @Test def max_fiveGreaterThenFour() { assertEquals(5, max.max(5, 4)); } }
Scala als DSL Toolkit
Internal DSLs mit Scala
Robot DSLobject DemoRobot extends RobotProgram with Application {
000 PRINT "Lunar Mars Program starts." 001 MOVE(1, 10) 002 SLEEP2000 003 MOVE(10, 10) 004 PRINT"POSITION Now 10, 10" 005 MOVE(20, 20) 006 END RUN
}
External DSLs mit Scala
Fragen ?
References
• Scala – http://www.scala-lang.org/• Scala IDE - http://www.scala-ide.org/• Scala Code Snippets
http://www.scala-lang.org/node/220• Scala By Example
http://www.scala-lang.org/docu/files/ScalaByExample.pdf
• Scala Tutorialhttp://www.scala-lang.org/docu/files/ScalaTutorial.pdf
• Scala Actors - http://www.scala-lang.org/node/242
• Lift http://liftweb.net