KONTROLLABSTRAKTION (NEUE KONTROLLSTRUKTUREN)

Werbung
Scala
Java-Nachfolger oder akademisches Experiment?
KONTROLLABSTRAKTION
(NEUE KONTROLLSTRUKTUREN)
Gliederung
Einleitung
Nutzung der Standard Kontrollstrukturen
if – else, for, do – while, while, match, try – catch
Spezielle Kontrollstrukturen
z.B. exists
Die verfügbaren Mittel
First-class-functions , Higher-order-functions,
Currying, By-name-Parameter
Neue Kontrollstrukturen
Beispiele neuer Kontrollstrukturen
Fazit
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
2
Einleitung
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
„Kontrollstrukturen (Steuerkonstrukte) werden in imperativen Programmiersprachen verwendet, um den Ablauf eines Computerprogramms zu steuern.
Eine Kontrollstruktur gehört entweder zur Gruppe der Verzweigungen oder
der Schleifen. Meist wird ihre Ausführung über logische Ausdrücke der
booleschen Algebra beeinflusst…“
(Quelle: Wikipedia)
Scala hat nicht viele Kontrollstrukturen
Integrierte Bestandteile sind so
implementiert, dass neue, eigene erstellt
werden können
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
3
Standard Kontrollstrukturen
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Scala bietet folgende integrierte, elementare
Kontrollstrukturen
Sie lassen sich benutzen, um eigene zu
kreieren
if-else
while, do-while
for
match
try-catch
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
4
Nutzung von if-else
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
In Scala hat die if, else - Kontrollstruktur einen
beliebigen Rückgabewert ( in Java nicht)
So kann in Scala der Inhalt einer Variablen von
einer Bedingung abhängig gemacht werden.
String t = "";
if (checkValue % 2 == 0) t="gerade"; else t = "ungerade";
System.out.println("checkValue "+ checkValue +" ist "+ t) ;
val check = if (checkValue % 2 == 0) log(checkValue) else "ungerade"
println("checkValue "+ checkValue +" ist "+ check)
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
5
Nutzung von Schleifen-KS
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Kontrollstruktur „while“ gibt ausschließlich ein
Objekt vom Typ Unit zurück
Nicht geeignet für eigene Kontrollstrukturen
Äquivalent dazu verhält sich „do – while“
Mit „for“ kann ein Ergebnis über „yield“
zurückgegeben werden
Umfangreiche Prüfmechanismen machen die
Schleifen zu einem mächtigen Werkzeug
In Scala (2.7) kein „break“ oder „continue“
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
6
Beispiele „while“ & „for“
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
var index = 0;
val testString = “TestString“
val back = while (index < testString.length) {
println(testString(index))
index += 1;
}; println(back) // Unit()
def even(from: Int, to: Int): List[Int] =
for (i <- List.range(from, to) if i % 2 == 0)
yield i
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
7
break und continue
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
object BreakLoop {
object Break extends RuntimeException;
object Continue extends Exception;
def break { throw Break }
def continue { throw Continue }
def whileTrue(block: => Unit) {
try {
while (true) try {
block }
catch { case Continue => } }
catch { case Break => } }
def whileTrue(condition: => Boolean) (block: => Unit) {
try {
while (condition)
try { block }
catch { case Continue => } }
catch { case Break => } } }
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
8
Beispiel break & continue
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
import util.BreakLoop._
object TestBreak extends Application {
var i = 0;
whileTrue
{
i += 1
if (i < 3) continue
if (i >= 5) break
}
}
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
9
Wiederholung (match)
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
match ist das Scala Gegenstück zu Java's switch,
aber weit aus mächtiger
Mit Hilfe von match können in Scala auch
Objekte zur Fallbestimmung herangezogen
werden Implizites break
def matchTest(x: Any): Any = x match {
case 1 => "one“
case "two" => 2
case "two" => 2
// Fehler: Unreachable Code
case y: Int => "scala.Int"
}
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
10
Spezielle Kontrollstrukturen
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Scala benutzt implizit eigene Mittel, für
Erweiterungen z.B. Methode exists für (List, Set,
Array und Map )
Standardlösung zum finden eines Objekts in einer Collection
def containsNeg(nums: List[Int]): Boolean = {
var exists = false
for (num <- nums)
if (num < 0)
exists = true
exists
}
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
11
Spezielle Kontrollstrukturen
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Standardlösung zum finden eines Objekts in einer Collection
def containsNeg(nums: List[Int]): Boolean = {
var exists = false
for (num <- nums)
if (num < 0)
exists = true
exists
}
Lösung mittels higher-order-functions
def containsNeg(nums: List[Int]) = nums.exists(_ < 0)
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
12
Die Mittel -
first-class-functions
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Thema des letzten Vortrages
Funktionen können als Code (function
literals) niedergeschrieben oder als
Funktionswerte (function values ) zur
Laufzeit übergeben werden
Bsp: (x : Int) => x + 1
Das “=>” bewirkt, das die Funktion den linken Teil
(irgendein Int “x” ) in den rechten Teil (x + 1) umwandelt
(Mapping)
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
13
Die Mittel –
higher-order-functions
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Funktionen, die Funktionen als Parameter
haben können
Vorteil: Hilft bei der Minimierung von
doppeltem Code
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
14
Beispiel
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
class FileMatcher {
private def filesHere = (new java.io.File(".")).listFiles
private def filesMatching(matcher: String => Boolean) =
for (file <- filesHere; if matcher(file.getName))
yield file
def filesEnding(query: String) =
filesMatching(_.endsWith(query))
def filesContaining(query: String) =
filesMatching(_.contains(query))
def filesRegex(query: String) =
filesMatching(_.matches(query))
}
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
15
Die Mittel –
Currying
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
„Currying ist die Umwandlung einer Funktion mit
mehreren Argumenten in mehrere Funktionen mit je
einem Argument…“
(Quelle: Wikipedia)
Wird benutzt um abstrahierte
Kontrollstrukturen wie Spracherweiterungen
aussehen zu lassen
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
16
Die Mittel –
Currying
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
def plainOldSum(x: Int, y: Int) = x + y
scala> plainOldSum(1, 2)
res4: Int = 3
def curriedSum(x: Int)(y: Int) = x + y
scala> curriedSum(1)(2)
res5: Int = 3
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
17
Die Mittel -
By-Name Parameter
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Möglichkeit Prüfbedingungen aufzurufen, ohne
sie auszuwerten
Bsp. Assertion Standard
var assertionEnabled = false
def boolAssert(predicate : Boolean) =
if(assertionEnabled && !predicate)
throw new AssertionError
boolAssert(5/0 == 0)
Führt zu:
Exception in thread "main" java.lang.ArithmeticException: / by zero
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
18
Die Mittel -
By-Name Parameter
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Bei Aufruf mit By-Name
var assertionEnabled = false
def byNameAssert(predicate : => Boolean) =
if(assertionEnabled && !predicate)
throw new AssertionError
byNameAssert(5/0 == 0) gibt nichts zurück
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
19
Neue Kontrollstrukturen
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Möglichkeit eigene Kontrollstrukturen zu
definieren
syntaktisch wie integrierte Kontrollstrukturen
First-class-Funktionen sind dabei das
wichtigste Werkzeug
Oderskys Empfehlung: Bei jedem, sich
wiederholenden control pattern, sollte man
darüber nachdenken diesen als neue
Kontrollstruktur zu implementieren
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
20
Einfache Beispiele
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Function
Value
Parameter
of Function
Value
converted
in Double
def twice(op: Double => Double, x: Double) = op(op(x))
Double
Parameter
scala> twice(_ + 1, 5)
Result: Double = 7.0
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
21
Einfache Beispiele
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Eigene MyWhile-Schleife – aber wie????
1. Was wird benötigt?
Methodenname
Bedingung, die überprüft wird
Methodenrumpf, der ausgeführt werden kann
2. Welche Möglichkeiten sind geeignet?
first-class & higher-order Funktionen
var x = 0
by-name-Parameter
myWhile (x < 10) {
currying
println(x)
x=x+1
}
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
22
Einfache Beispiele
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Methodendefinition
var x = 0
myWhile (x < 10) {
println(x)
x=x+1
}
def myWhile(„Bedingung“ , „AusführbarerCode“) …
Darf die Bedingung ausgewertet werden?
Nein! By-Name-Parameter
def myWhile(„Bedingung“: => , „AusführbarerCode“) …
Typ für den Funktionswert sicherstellen!!!
def myWhile(condition: => Boolean , „AusführbarerCode“) …
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
23
Einfache Beispiele
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
function-values setzen
var x = 0
myWhile (x < 10) {
println(x)
x=x+1
}
def myWhile(condition: => Boolean , operation ) …
Egal, welcher Code ausgeführt werden soll
kein spez. Rückgabetyp Unit
def myWhile(condition: => Boolean , operation: => Unit )
Probleme:
Aufruf erlaubt nur einen Funktionswert, als
Parameter
Currying ermöglicht Austausch der Klammern
def myWhile(condition: => Boolean) (operation: => Unit )
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
24
Einfache Beispiele
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Codeausführung über Rekursion
def myWhile(condition: => Boolean, operation: => Unit){
operation
if(condition){ myWhile(condition, operation)}
}
Der Aufruf – wie gewünscht
var x = 0
myWhile (x < 10) {
println(x)
x=x+1
}
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
25
Loan Pattern
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Loan ( = die Leihe)
def withPrintWriter(file : File)(op : PrintWriter => Unit) {
val writer = new PrintWriter(file)
try{
op(writer)
} finally {
writer.close()
}
}
Look and Feel -> Ersetzen von “(“ durch “{“
Nur möglich bei einem Argument Currying
withPrintWriter(file) {
writer => writer.println(new java.util.Date)
}
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
26
Generische Rückgabe
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
value expressions können automatisch in
Funktionen konvertiert werden
def unless[A](condition: Boolean, ifTrue : => A, ifFalse : => A) =
if (condition) ifTrue else ifFalse
unless(true, throw new Error, "Hello!")
⇒"Hello!“
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
27
Eigene Kontrollstrukturen
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Closeable-Objekte immer schließen
object ClosingTest {
type CloseType = { def close() }
def manage(resource: CloseType) (block: => Unit) = {
try{
block
} finally {
println("Closing...")
resource.close()
println("Closed!!! ") }}
def main(args : Array[String]) : Unit ={
val reader = new BufferedReader(new FileReader("src\\test.txt"))
manage(reader) {
var line: String = reader.readLine
while (line != null) {
println(line)
line = reader.readLine} }}}
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
28
Fazit
Gliederung
•Einleitung
•Standard KS
•Spezielle KS
•Mittel
•Neue KS
•Fazit
Kurzer Code erschwert debuggen
Code-Stil wird schnell verwirrend
Unglaublich mächtig, jedoch nicht mehr lesbar
Unübersichtlicher Code erschwert
Typsicherheit
Ist kürzerer Code immer der Bessere?
Kontrollabstraktion (neue Kontrollstrukturen) -- Florian Syska, Christian Wilhelmi
04.05.2010
29
Quellen:
Oderskys: Programming in Scala
http://daily-scala.blogspot.com
http://timpt.de/it/topic141.html
http://www.scala-lang.org/
http://en.wikipedia.org
http://www.ibm.com/developerworks/java/library/j-scala03268.html
http://termos.vemod.net/implementing-your-own-control-structures-inscala
VIELEN DANK FÜR IHRE
AUFMERKSAMKEIT!
Herunterladen