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 von
Web-Services stellt einen ParadigmenWechsel dar
Bedarf nach Unterstützung durch
Programmiersprachen entsteht
Ziele beim Entwurf
Verknüpfung von funktionaler und ObjektOrientierter Programmierung
Kein Flickwerk Synergie
Nahtlose Zusammenarbeit mit anderen
Objekt-Orientierten Sprachen
Pattern-Matching als Grundlage für
XML-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;
override def toString() = “x= “ + x;
}
class ColoredPoint(u: int, c: String) extends Point(u) {
var color = c;
override def toString() = super.toString() + “, c= “ + c;
}
class Point2D(xc:int, yc: int) extends Point(xc) {
val y = yc;
override def 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] = {
[...]
}
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);
}
def modN(x: Int): Boolean = {
((x % 2) == 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
Operatoren
Operatoren sind ebenfalls Objekte
Genauer: eine abkürzende Schreibweise
Formaler: Methoden, die einen Parameter
erwarten, in einer Infix-Notation
b = a + 3;
b = a.+(3);
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;
}
private static void swap(int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
Benchmark-Ergebnisse
6
5
4
3
2
1
0
100.000
1.000.000
Java
10.000.000
Scala OO
Scala Fkt
100.000.000
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
Vielen Dank für Ihre
Aufmerksamkeit.