330 likes | 509 Views
Scala. Vortrag im Rahmen des Seminars „Programmiersprachen“ David Ullrich. In diesem Vortrag erwartet Sie:. Einführung Besonderheiten der Sprache Beispiel-Anwendung: QuickSort Zusammenfassung. Einführung. Der Ursprung Gründe für eine neue Sprache Zielsetzung beim Entwurf. Der Ursprung.
E N D
Scala Vortrag im Rahmen des Seminars „Programmiersprachen“David Ullrich
In diesem Vortrag erwartet Sie: • Einführung • Besonderheiten der Sprache • Beispiel-Anwendung: QuickSort • Zusammenfassung
Einführung • Der Ursprung • Gründe für eine neue Sprache • Zielsetzung beim Entwurf
Der Ursprung • Prof. Martin Odersky (Pizza, GJ) • Programming Methods Laboratory - LAMP • Seit 2002 in der Entwicklung • Erste Veröffentlichung Januar 2004
Gründe für eine neue Sprache(nach Odersky) • Zunehmende Verbreitung vonWeb-Services stellt einen Paradigmen-Wechsel dar • Bedarf nach Unterstützung durch Programmiersprachen entsteht
Ziele beim Entwurf • Verknüpfung von funktionaler und Objekt-Orientierter Programmierung • Kein Flickwerk Synergie • Nahtlose Zusammenarbeit mit anderen Objekt-Orientierten Sprachen • Pattern-Matching als Grundlage fürXML-Bearbeitung
Besonderheiten der Sprache • Das Typsystem • Klassen und Vererbung • Funktionen • Framework-Integration • Fortgeschrittene Konzepte
Das Typsystem • „Alles ist ein Objekt“ • klassische Objekte aus der OOP • Funktionen Werte Objekte object ObjektDemo {def main(args: Array[String]): unit = System.out.println(main.toString());}
Objekthierarchie in Scala (Auswahl) scala.Any scala.AnyVal scala.AnyRef (java.lang.Object) scala.Char scala.Int scala.Object java.lang.String
Benutzerdefinierte Typumwandlung • Werttypen besitzen bereits verschiedene coerce-Methoden (Byte Short Int) • coerce-Methoden werden implizit aufgerufen def coerce: String = { [...]}
Klassen und Vererbung • Singleton-Objekte • Klasseninstanzen • Vererbung • mixin-composition • generische Klassen • type-bounds
Singleton-Objekte • Schlüsselwort object • Referenzierung über den Objektnamen • main-Methode bildet Startpunkt object HelloWorld {def main(args: Array[String]): unit = System.out.println(“Hello World!“);} object HelloWorld with Application { System.out.println(“Hello World!“);}
Klasseninstanzen • Schlüsselwort class zur Definition • Schlüsselwort new zur Instanziierung • keine Konstruktoren • stattdessen Parameterliste class Klassendemo(a:int) {val x = a;}
Vererbung • Einfachvererbung mit Schlüsselwort extends • Schnittstellen-Definition über trait • abstract Klassen nur Oberklassen • sealed Klassen nie Oberklassen • Überladen mit override • Signatur bei Überladen änderbar
Schnittstellendefinition • Schnittstellen haben keinen Zustand • Parameter deshalb nicht erlaubt • enthält Methodensignaturen • können Methoden implementieren • können andere Schnittstellen erweitern trait TraitDemo {def abstractMethod(x: any): unit;def concreteMethod(x: any): String = x.toString();}
mixin-composition • Unter geeigneten Umständen kann eine Klasse auch die nur die neuen Methoden erben • Die Klasse mit den neuen Methoden heißt mixin • Funktioniert nur, wenn die Oberklasse des mixins eine Oberklasse der Oberklasse der zu erweiternden Klasse ist
mixin-Beispiel class Point(xc: int) {val x = xc;overridedef toString() = “x= “ + x;}class ColoredPoint(u: int, c: String) extends Point(u) {var color = c;overridedef toString() = super.toString() + “, c= “ + c;}class Point2D(xc:int, yc: int) extends Point(xc) { val y = yc;overridedef toString() = super.toString() + “, y= “ + y; } class ColoredPoint2D(xc: int, yc: int, c: String)extends Point2D(xc, yc)with ColoredPoint(xc, c);}
generische Klassen • Objekttyp wird als Parameter in eckigen Klammern übergeben • Parametername kann nun wie ein Typbezeichner verwendet werden class generischesBeispiel[a](xc: a) {val x: a = xc;} [...] (args: Array[String]) [...]
type-bounds • können Typ-Parameter einschränken • lower-type-bound: Typ-Parameter T muss Oberklasse eines anderen Typs A sein T >: A • upper-type-bound: Typ-Parameter T muss eine definierte Oberklasse A haben T <: A
Funktionen • Parameter • polymorphe Funktionen • Currying • anonyme Funktionen • Operatoren
Parameter • Übergabe erfolgt in Parameterlisten • Typangabe nach Typbezeichner • Anzahl der Parameterlisten beliebig • Funktionen selbst als Parameter möglich „Funktionen höherer Ordnung“ def fktBsp2(f: int => String, v: int): String = { f(v);} def fktBsp(a: int, b: String): unit = { [...]}
Polymorphe Funktionen • sind generische Methoden • lassen sich mit Typ-Parameter versehen • lassen sich mit type-bounds einschränken • kein Bruch zwischen Klassen und Funktionen def polyBsp[T](x: T, n: Int): List[T] = { [...]}
def modN(x: Int): Boolean = { ((x % 2) == 0);} Currying • Angabe mehrerer Parameterlisten erlaubt allgemeinere Methoden • Aufruf übergibt Parameterlisten und liefert eine Referenz auf eine „konfigurierte“ Methode def modN(n: Int)(x: Int): Boolean = { ((x % n) == 0);} modN(2)
Anonyme Funktionen • ermöglichen Methodendefinition ohne Bezeichner • Sinnvoll bei Aufruf an einer Stelle im Code • implizite Definition erfolgt durch Compiler • Parameter-Rumpf-Trennung durch => (x: int, y: int) => x * y
b = a + 3; b = a.+(3); Operatoren • Operatoren sind ebenfalls Objekte • Genauer: eine abkürzende Schreibweise • Formaler: Methoden, die einen Parameter erwarten, in einer Infix-Notation
Framework-Integration • Nahtlose Interaktion mit der JRE oder der CLR war ein Entwicklungsziel • Scala derzeit ein Wrapper für JVM und Java Compiler • java.lang.* ist bereits importiert • Compile-Ergebnis ist Bytecode
Fortgeschrittene Konzepte • Local Type Inference • Pattern-Matching • Regular Expression Patterns • Case-Classes • native XML-Unterstützung • Sequence Comprehensions for (val i: int <- Iterator.region(0, 23)) { [...]} for (val i: int <- Iterator.region(0, 23); i % 2 == 0) { [...]}
Beispiel-Anwendung: QuickSort • Scala-Implementierung OO und funktional • Funktionale Implementierung vertauscht nicht, sondern filtert def sort(a: List[int]): List[int] = { if (a.length < 2) { a } else { val pivot = a(a.length / 2); sort(a.filter(x => x < pivot)) ::: a.filter(x => x == pivot) ::: sort(a.filter(x => x > pivot)); } }
QuickSort in Java • Java-Code im Wesentlichen durch„Schlüsselwort-Transformation“ def swap(i: int, j: int): unit = { val t = a(i); a(i) = a(j); a(j) = t; } privatestaticvoid swap(int i, int j) { int t = a[i]; a[i] = a[j]; a[j] = t; }
Zusammenfassung • Einige Interessante Möglichkeiten • Mainstream-Features der nahen Zukunft • Gute Integration • Schnell genug für den täglichen Einsatz • Scala ist noch nicht fertig
Abschließend ... Scala (ital. Treppe) ist vielleicht nicht DER nächste Schritt, aber ein Schritt in die richtige Richtung