Scala

Werbung
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.
Herunterladen