Scala (Programmiersprache)
Scala | |
---|---|
![]() | |
Basisdaten | |
Paradigmen: | objektorientiert, funktional |
Erscheinungsjahr: | Seit 2001: Interne Arbeiten am EPFL 2003: Version 1 2006: Version 2 |
Designer: | Martin Odersky |
Entwickler: | École polytechnique fédérale de Lausanne unter Leitung von Martin Odersky |
Aktuelle Version: | 2.8.1 (November 2010) |
Typisierung: | statisch typisiert |
Beeinflusst von: | Java, ML, Haskell, Smalltalk, Erlang |
Betriebssystem: | plattformunabhängig |
Lizenz: | Scala[1], BSD ähnlich |
scala-lang.org |
Scala ist eine funktionale und objektorientierte Programmiersprache. Sie kann auf einer JVM oder .NET VM ausgeführt werden.
Der Name leitet sich von 'scalable language' ab und bringt zum Ausdruck, dass der sehr kompakt gehaltene Sprachkern die Möglichkeit bietet, häufig verwendete Sprachelemente wie z. B. Operatoren oder zusätzliche Kontrollstrukturen in Benutzerklassen zu implementieren und dadurch den Sprachumfang zu erweitern und eigene DSLs zu erstellen.
Beispiel
Beispiel eines Hello, World!-Programms in Scala:
object HelloWorld extends Application {
println("Hello, world!")
}
Geschichte
Scala wird am Labor für Programmiermethoden an der École polytechnique fédérale de Lausanne unter der Leitung von Martin Odersky entwickelt.
Martin Odersky arbeitete unter Niklaus Wirth an Modula 2 und Oberon. Ab 1995 entwickelte er zusammen mit Philip Wadler die Sprache Pizza, die Java um Generics, Funktionszeiger und Pattern Matching erweiterte. Später konzentrierten sich Wadler und Odersky mit GJ (Generic Java) auf Generics für Java, dieses Projekt führte 2004 zur Einführung von Generics in Java[2]. Ab 1999 arbeitete Martin Odersky an der École polytechnique fédérale de Lausanne, wo er an der Verbindung funktionaler und objektorientierter Programmierung forschte und die minimalistische Hybridsprache Funnel entwickelte. Hier begann er 2001 mit der Entwicklung von Scala, die im Gegensatz zu Funnel nicht rein akademischem Interesse dienen sollte, sondern als vollwertige Sprache für reale Anwendungen ausgelegt war. Im Frühjahr 2004 wurde Scala für die Java-Platform veröffentlicht, im Juni 2004 für .NET.
Wesentliche Neuerungen im aktuellen Release 2.8[3]:
- Überarbeitung der Collection-Library[4]
- Überarbeitung der Array-Implementierung[5]
- benannte Argumente und Defaultwerte für Argumente[6]
- Delimited Continuations
- Erweiterungen für Aktoren-Nebenläufigkeit
- Package-Objekte, die Methoden und Werte für ein Package zur Verfügung stellen
Konzepte
- Integration mit Java[7]
- Scala-Programme können Java-JARs ansprechen und umgekehrt. Es können also alle bestehenden Java-Librarys und -Frameworks in Scala-Projekte eingebunden und dort genutzt werden. Ähnliches gilt für die meisten Tools: Entwicklungsumgebungen wie Eclipse, NetBeans oder IntelliJ unterstützen Scala ebenfalls.
- Objektorientierung
- Scala ist im Gegensatz zu Java eine rein objektorientierte Sprache. Jeder Wert ist ein Objekt. Das gilt auch für primitive Datentypen, ohne dass es zu Performanceeinbußen kommt, denn der vom Compiler erzeugte Bytecode verwendet primitive Datentypen.
- Interfaces werden über den Mechanismus der Traits implementiert. Traits bestehen nicht nur aus Definitionen, sie können bereits konkrete Implementierungen von Methoden enthalten. Klassen können einen oder mehrere Traits "extenden".[8]/[1] Dabei handelt es sich nicht um Mehrfachvererbung, sondern um einen Mixin-Mechanismus.
- Über das Schlüsselwort
object
(anstelle vonclass
) wird eine Implementierung des Design Pattern Singleton bereitgestellt.
- Funktionale Sprache
- Funktionen sind First-Class-Objekte. Sie können an allen Stellen verwendet werden, an denen Werte erlaubt sind, z. B. Zuweisung an eine Variable (hier ist nicht das Ergebnis der Funktionsauswertung gemeint, sondern die Funktionen selbst) oder bei der Parameterübergabe. Methoden können jederzeit in Funktionen umgewandelt werden, sind selbst aber keine First-Class-Objekte.
- Funktionen höherer Ordnung[9]
- Currying: Falls die Signatur einer Methode
n
Parameterlisten enthält aber mit nur1
Parameterliste aufgerufen wird, liefert sie unter Verwendung des übergebenen Parameters eine (unbenannte) Methode mitn-1
Parameterlisten zurück.[10] - Ein wichtiger Aspekt zur Unterstützung der funktionalen Programmierung mit Scala ist Pattern Matching. Im Gegensatz zu der switch Anweisung wie sie zum Beispiel in Java implementiert ist, arbeitet Pattern Matching nicht nur auf der Basis von Werten sondern auch bezogen auf die Struktur bzw. den Typ eines Objektes. Unter anderem hierfür wurden Case Classes[11] in Scala implementiert.
- Closures: Funktionen greifen nicht nur auf ihre Parameter und lokalen Variablen zu, sondern auch auf Variablen ihres Kontextes (Scope), welche zum Auswertungszeitpunkt gültig sind. Dadurch werden aus open terms die namensgebenden closed terms. Falls sich bei mehrfacher Verwendung der Funktion der Wert einer Variablen des Kontextes gegenüber einem früheren Auswertungszeitpunkt ändert, kann sich auch der Rückgabewert und das Verhalten der Funktion ändern.
- Typsystem
- Scala ist statisch typisiert.
- Generische Klassen verwenden Typen, die zum Entwicklungszeitpunkt noch nicht festgelegt sind, z. B.
List[T]
- Oberklassen können abstrakte Typen[12] vorgeben, die von deren Unterklassen in Form konkreter Typen spezifiziert werden müssen. Gleiches gilt für Variablen (
var
undval
) sowie Methoden. - Kovarianz und Kontravarianz. Typparameter einer generischen Klasse können mit einer Annotation versehen werden, die bestimmt, wie sich Untertyprelationen von Typargumenten auf die Untertyprelation von generischen Instanziierungen der Klasse auswirken. Invarianz, Syntax:
K[T]
, bedeutet, dass überhaupt kein Zusammenhang besteht. Kovarianz, Syntax:K[+T]
, bedeutet, dass sich die Relation in gleicher Richtung fortsetzt: WennT
Untertyp vonU
ist, dann istK[T]
Untertyp vonK[U]
. Kontravarianz, Syntax:K[-T]
, bedeutet, dass die Fortsetzung in der Gegenrichtung erfolgt: WennT
Untertyp vonU
ist, dann istK[U]
Untertyp vonK[T]
. Varianzannotationen beeinflussen, an welcher Stelle innerhalb der generischen Klasse der Typparameter benutzt werden darf: Kovariante Typparameter dürfen beispielsweise nicht als Typ von Methodenargumenten verwendet werden, kontravariante nicht als Rückgabetyp.[13] - Typinferenz ist eine Eigenschaft des Compilers, welche unter Scala_(Programmiersprache)#Syntax beispielhaft dargestellt ist.
- Auswertungsstrategie
- Funktionale Ausdrücke werden in Scala strikt ausgewertet. Allerdings kann durch Annotationen die verzögerte Auswertung (Lazy-Evaluation) von einzelnen Ausdrücken spezifiziert werden. Im Gegensatz hierzu werden in Haskell die Programme standardmäßig lazy ausgewertet und es existieren Strictness Annotationen.
- XML
- Zum Sprachumfang gehören "out of the box" grundlegende XML-Operationen und -Datentypen: XML Literale, Konstruktoren, Serialisierung und Deserialisierung, XPath-ähnliche Extraktion von Elementen und Attributen:
val liste = <einkaufsliste>
<artikel><name>Brot</name><preis>3.50</preis></artikel>
<artikel><name>Apfel</name><preis>0.29</preis></artikel>
<artikel><name>Eier</name><preis>1.19</preis></artikel>
</einkaufsliste>
val gesamtpreis = liste \\ "preis" map (_.text.toDouble) sum //Ergebnis: 4.98
- Implicits
- Methoden können mittels des Modifiers
implicit
zu sogenannten implicit methods werden. Wenn der Compiler ein Objekt eines bestimmten Typs A erwartet, aber ein Objekt des inkompatiblen Typs B vorfindet, sucht er im lexikalischen Scope und im companion object von A nach einer implicit method mit der er das B-Objekt in ein A-Objekt konvertieren kann. Mit dieser Technik lassen sich die aus C# bekannten extension methods nachbilden (das sogenannte pimp my library-Pattern) und in Grenzen sogar Vererbung. - Die letzte Parameter-Liste einer Methode kann ebenfalls als implicit markiert werden. Wenn die Parameterliste beim Aufruf einer Methode fehlt, aber ein als implicit markierter Wert im lexikalischen Scope zu finden ist, wird er automatisch an die Methode übergeben. Hiermit ist es möglich, die aus Haskell bekannten type classes nachzubilden.[14]
- Methoden können mittels des Modifiers
- Nebenläufigkeit
Syntax
- Die Syntax der Sprache ist an Java und ML angelehnt. Von Java wurde vor allem eine Reihe von Schlüsselworten sowie die Blocksyntax übernommen, von ML die Syntax für Typannotationen und Deklarationen.
- Im Vergleich mit Java ist der Sourcecode deutlich kompakter. In den meisten Fällen kann das Semikolon am Ende einer Zeile entfallen. Man formuliert nicht sondern
Typ variable
In gleicher Weise gibt man den Typ des Rückgabewertes einer Methode an:variable: Typ
f(var1: Typ, var2: Typ): Typ
- Deklaration und Definition von Werten, Variablen und Methoden mittels der Schlüsselwörter
val
,var
unddef
, gefolgt von Typangaben.val wert: Int = 42
var variable: Double = 3.14
def methode(parameter1: String, parameter2: Boolean): Unit
- Typinferenz: Der Compiler den Typ einer Variable aus dem Kontext herleiten. Die beiden Zeilen und
var x = "Ein Text"
sind somit gleichwertig.var x: String = "Ein Text"
- Klassen- und Methodennamen können einen großen Umfang von Zeichen und Symbolen nutzen. Es sind z. B. Bezeichner wie +, *, ::, \\ oder isEmpty_? erlaubt.
- Methodenaufrufe mit keinem oder einem Parameter können unter Auslassung des Punktes und der öffnenden und schließenden runden Klammern notiert werden (ähnlich wie in Smalltalk oder Objective-C):
5.0.+(2.0)
"Test".startsWith("T")
entsprichtList(1,2,3).isEmpty
5.0 + 2.0
"Test" startsWith "T"
List(1,2,3) isEmpty
- Für Präfix-Operatoren gibt es eine fest vorgegebene Menge, nämlich +,-,~ und !. Der Ausdruck
-x
bedeutet das gleiche wiex.unary_-
- Postfix-Operator-Ausdrücke sind ebenfalls möglich. Hier gibt es keine Einschränkungen an den Operator, und das Übersetzungsergebnis ist ein Aufruf der (parameterlosen) Methode auf dem Operanden.
- Bei Infix-Operatoren entscheidet das erste Zeichen des Operatornamens über Präzedenz und Assoziativität, das den aus der Mathematik übleichen Konventionen folgt. Das Codefragment wird übersetzt zu
1 + z*x
Auf dem Objekt(1).+(z.*(x))
1
wird die Methode+
aufgerufen und dabei der Parameterz.*(x)
, also das Ergebnis eines weiteren Methodenaufrufes, übergeben. - Beginnt der Methodenname eines Infixoperators mit einem Doppelpunkt, so vertauscht sich die Reihenfolge von Empfänger und Parameter und der Operator ist rechtsassoziativ: wird übersetzt zu
a :: b
b.::(a)
- Für Präfix-Operatoren gibt es eine fest vorgegebene Menge, nämlich +,-,~ und !. Der Ausdruck
- For-Schleifen wurden soweit generalisiert, dass sie nicht nur mehrere verschachtelte Schleifen zusammenfassen, sondern analog zu Haskells do-Notation beliebige Monaden nutzen können.
IDEs und Frameworks
Neben dem Compiler scalac
steht eine Read-Evaluate-Print-Loop (REPL) namens scala
zur Verfügung. Für die IDEs Eclipse,[15] NetBeans[16] und IntelliJ[17] existieren Plugins. Das Framework Lift zur Entwicklung von Web-Applikationen sowie weitere Frameworks[18] bauen auf Scala auf. Ergänzend zur Aktoren- Implementierung der Scala Klassenbibliothek gibt es noch weitere Implementierungen von Aktoren in den folgenden Frameworks: Lift, Akka [19] und Scalaz [20].
Scalaz enthält außerdem viele weitere Konstrukte welche die funktionale Programmierung in Scala erleichtern. Für den Erstellungsprozess unterstützt Scala u. a. Ant oder Maven, stellt aber auch ein eigenes Framework zur Verfügung: das "Simple Build Tool" [21].
Verwendung
Die sozialen Netzwerke Twitter und LinkedIn haben ihre Nachrichten-Warteschlangen in Scala implementiert.[22][23]
Scala hat mittlerweile auch Anwendung in der Industrie gefunden. Weitere populäre Verwender sind Siemens, Sony oder Électricité de France Trading.[24]
Siehe auch
Einzelnachweise
- ↑ Lizenz
- ↑ Generics in Java
- ↑ Release 2.8
- ↑ Collection-Library
- ↑ Array-Implementierung
- ↑ benannte Argumente und Defaultwerte für Argumente
- ↑ Englischsprachige Zusammenfassung
- ↑ Traits
- ↑ Funktion höherer Ordnung
- ↑ Parameterlisten
- ↑ Case Classes
- ↑ Abstrakte Typen
- ↑ Rückgabetyp
- ↑ Type classes (PDF)
- ↑ http://www.scala-ide.org
- ↑ http://wiki.netbeans.org/Scala
- ↑ http://plugins.intellij.net/plugin/?id=1347
- ↑ http://www.scala-lang.org/node/1209#libraries
- ↑ http://akkasource.org/
- ↑ http://code.google.com/p/scalaz/
- ↑ http://code.google.com/p/simple-build-tool/
- ↑ http://www.artima.com/scalazine/articles/twitter_on_scala.html
- ↑ http://days2010.scala-lang.org/node/138/159
- ↑ http://www.scala-lang.org/node/1658
Literatur
- Martin Odersky, Lex Spoon, Bill Venners: Programming in Scala. Computer Bookshops, 2008, ISBN 0-9815316-0-1 (englisch).
- Dean Wampler, Alex Payne: Programming Scala. O'Reilly, 2009, ISBN 978-0-596-15595-7, S. 448 (HTML-Version).
- Lothar Piepmeyer: Grundkurs funktionale Programmierung mit Scala. Hanser, 2010, ISBN 978-3-446-42092-2, S. 297.
Weblinks
- Scala Website
- The Scala Language Specification
- Audiocast-Interviews mit Martin Odersky: Umfassende Einführung, Geschichte und Besprechung der Merkmale von Scala (Juli 2007) Neuerungen seit 2007, geplante Entwicklungen und Anwendungsbereiche von Scala (Februar 2011)
- JavaSPEKTRUM, 2010, Einführung in Scala Teil 1 Teil 2 Teil 3
- Scala Tutorial