Praktische Informatik 3: Funktionale Programmierung Vorlesung 13 vom 24.01.17: Scala — Eine praktische Einführung
Christoph Lüth Universität Bremen Wintersemester 2016/17
09:29:49 2017-01-25 1 [18]
Fahrplan
I Teil I: Funktionale Programmierung im Kleinen I Teil II: Funktionale Programmierung im Großen I Teil III: Funktionale Programmierung im richtigen Leben
IAktionen und Zustände
IMonaden als Berechnungsmuster
IDomänenspezifische Sprachen (DSLs)
I Scala — Eine praktische Einführung
IRückblich & Ausblick
PI3 WS 16/17 2 [18]
Organisatorisches
I Anmeldung zu den Fachgesprächen ab sofort möglich
I Unterstud.ip, Reiter „Terminvergabe“
I Nächste Woche noch mehr zu den Fachgesprächen
I Es gibt eine Liste mit Übungsfragen (auf der Homepage, unter Übungsblätter)
PI3 WS 16/17 3 [18]
Heute: Scala
I Ascalablelanguage
I Rein objektorientiert
I Funktional
I Eine “JVM-Sprache”
I Seit 2004 von Martin Odersky, EPFL Lausanne (http://www.scala-lang.org/).
I Seit 2011 kommerziell durch Lightbend Inc. (formerly Typesafe)
PI3 WS 16/17 4 [18]
Scala am Beispiel: 01-GCD.scala
Was sehen wir hier?
defgcdLoop(x : Long , y : Long) : Long = { vara = x
varb = y while(a != 0) {
valtemp = a a = b % a b = temp } returnb }
defgcd(x : Long , y : Long) : Long = i f(y == 0) xelsegcd (y , x % y)
I Variablen, veränderlich (var)
I Mit Vorsicht benutzen!
I Werte, unveränderlich (val) I while-Schleifen
I Unnötig!
I Rekursion
I Endrekursion wird optimiert I Typinferenz
I Mehr als Java, weniger als Haskell I Interaktive Auswertung
PI3 WS 16/17 5 [18]
Scala am Beispiel: 02-Rational-1.scala
Was sehen wir hier?
classRational (n : Int , d : Int ) { require (d != 0)
private valg = gcd(n . abs , d . abs) valnumer = n / g
valdenom = d / g def this(n : Int ) =this(n , 1) defadd( that : Rational ) : Rational =
newRational (
numer∗that .denom + that . numer∗ denom,
denom∗that .denom )
override deftoString = numer +"/"+ denom private defgcd(a : Int , b : Int ) : Int =
i f(b == 0) aelsegcd(b , a % b) }
IKlassenparameter IKonstruktoren (this)
IKlassenvorbedingungen (require) Iprivate Werte und Methoden IMethoden, Syntax für
Methodenanwendung Ioverride(nicht optional) IOverloading
IOperatoren
ICompanion objects (object)
PI3 WS 16/17 6 [18]
Algebraische Datentypen: 03-Expr.scala
Was sehen wir hier?
abstract classExpr
case classVar(name: String )extendsExpr case classNumber(num: Double)extendsExpr case classUnOp( operator : String , arg : Expr)
extendsExpr
case classBinOp( operator : String , l e f t : Expr , r i g h t : Expr)extendsExpr
defeval ( expr : Expr) : Double = exprmatch{ casev : Var⇒0 // Variables evaluate to 0 caseNumber(x)⇒x
caseBinOp("+", e1 , e2)⇒eval (e1) + eval (e2) caseBinOp("∗", e1 , e2)⇒eval (e1)∗eval (e2) caseUnOp("−", e)⇒ −eval (e)
}
vale = BinOp("∗", Number(12) , UnOp("−", BinOp("+", Number(2.3) ,
Number(3.7) ) ) )
I case classerzeugt
I Factory-Methode für Konstruktoren
I Parameter als impliziteval
I abgeleitete Implementierung für toString,equals
I . . . und pattern matching (match) I Pattern sind
I case4 ⇒ Literale
I caseC(4) ⇒ Konstruktoren
I caseC(x) ⇒ Variablen
I caseC(\_)⇒ Wildcards
I casex: C ⇒ getypte pattern
I caseC(D(x: T, y) , 4)⇒ geschachtelt
PI3 WS 16/17 7 [18]
Implementierung algebraischer Datentypen
Haskell:
dataT = C1 |. . .| Cn
I Ein TypT
I Konstruktoren erzeugen Datentyp Scala:
T C1
. . . Cn
-
IVarianten alsSubtypen IProblem und Vorteil:
Erweiterbarkeit
Isealedverhindert Erweiterung
PI3 WS 16/17 8 [18]
Das Typsystem
Das Typsystem behebt mehrere Probleme von Java:
I Werte vs. Objekte
I Scala vs. Java
I NULLreferences
PI3 WS 16/17 9 [18]
Vererbungshierarchie
Quelle: Odersky, Spoon, Venners:Programming in Scala
PI3 WS 16/17 10 [18]
Parametrische Polymorphie
I Typparameter (wie in Haskell, Generics in Java), Bsp. List [T]
I Problem: Vererbung und Polymorphie I Ziel: wennS < T, dannList [S] < List [T]
I Does not work—04-Ref.hs I Warum?
I Funktionsraum nicht monoton im ersten Argument
I SeiX⊆Y, dannZ−→X⊆Z−→Y, aberX−→Z6⊆Y−→Z
I SondernY−→Z⊆X−→Z
PI3 WS 16/17 11 [18]
Typvarianz
class C[+T]
I Kovariant I WennS < T, dann
C[S] < C[T]
I ParametertypT nur im Wertebereichvon Methoden
class C[T]
I Rigide I Kein Subtyping I ParametertypT kannbeliebig verwendet werden
class C[−T]
IKontravariant IWennS < T, dann
C[T] < C[S]
IParametertypT nur im
Definitionsbereich von Methoden Beispiel:
class Function[−S, +T] { def apply (x :S) : T }
PI3 WS 16/17 12 [18]
Traits: 05-Funny.scala
Was sehen wir hier?
I Trait(Mix-ins): abstrakte Klassen, Interfaces; Haskell: Typklassen I „Abstrakte Klassen ohne Konstruktur“
I Unterschied zu Klassen:
I Mehrfachvererbung möglich
I Keine feste Oberklasse (superdynamisch gebunden)
I Nützlich zur Strukturierung (Aspektorientierung) I Nützlich zur Strukturierung:
thin interface+trait=rich interface Beispiel:05-Ordered.scala,05-Rational.scala
PI3 WS 16/17 13 [18]
More Traits
I Ad-Hoc Polymorphie mit Traits I Typklasse:
t r a i t Show[T] {
defshow( value : T) : String }
I Instanz:
implicit object ShowInt extendsShow[ Int ] { defshow( value : Int ) = value . toString }
I In Aktion:
def print [T] ( value : T) (implicit show : Show[T] )= { p r i n t l n (show . show( value ) ) ;
}
PI3 WS 16/17 14 [18]
Was wir ausgelassen haben. . .
I Komprehension(nicht nur für Listen)
I Gleichheit:==(final),equals(nicht final),eq(Referenzen) I ImpliziteParameter und Typkonversionen
I Nebenläufigkeit(Aktoren, Futures) I TypsichereMetaprogrammierung I Dassimple build toolsbt I Der JavaScript-Compilerscala . js
PI3 WS 16/17 15 [18]
Schlammschlacht der Programmiersprachen
Haskell Scala Java
Klassen und Objekte - + +
Funktionen höherer Ordnung + + -
Typinferenz + (+) -
Parametrische Polymorphie + + +
Ad-hoc-Polymorphie + + -
Typsichere Metaprogrammierung + + -
Alle: Nebenläufigkeit, Garbage Collection, FFI
PI3 WS 16/17 16 [18]
Scala — Die Sprache
I Objekt-orientiert:
I Veränderlicher, gekapselterZustand
I Subtypenund Vererbung
I KlassenundObjekte I Funktional:
I UnveränderlicheWerte
I Parametrische und Ad-hocPolymorphie
I Funktionen höherer Ordnung
I Hindley-MilnerTypinferenz
PI3 WS 16/17 17 [18]
Beurteilung
I Vorteile:
IFunktional programmieren, in der Java-Welt leben
IGelungene Integration funktionaler und OO-Konzepte
ISauberer Sprachentwurf, effiziente Implementierung, reiche Büchereien I Nachteile:
IManchmal etwaszuviel
IEntwickelt sich ständig weiter
IOne-Compiler-Language, vergleichsweise langsam I Mehr Scala?
IBesuchen Sie auchReaktive Programmierung(SoSe 2017)
PI3 WS 16/17 18 [18]