Scala (Programmiersprache)

Scala (Programmiersprache)
Scala
Paradigmen: objektorientiert, funktional, imperativ
Erscheinungsjahr: Seit 2001: Interne Arbeiten an der EPFL
2003: Version 1
2006: Version 2
Entwickler: École polytechnique fédérale de Lausanne unter Leitung von Martin Odersky
Aktuelle Version: 2.9.1  (31. August 2011)
Typisierung: statisch typisiert
Einflüsse: Java, Pizza, 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 Java Virtual Machine 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.

Inhaltsverzeichnis

Beispiele

Ein Hello, World!-Programm in Scala:

 object HelloWorld extends App {
     println("Hello, world!")
 }

Eine Implementierung des Quicksort-Algorithmus:

def quickSort[A <% Ordered[A]](xs: List[A]): List[A] = xs match {
   case Nil     => xs
   case y :: ys => ys partition (_ <= y) match { case (l1, l2) => quickSort(l1) ++ (y :: quickSort(l2)) }
}

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[3] 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.

Seit Anfang 2011 wird die Weiterentwicklung der Sprache vom European Research Council finanziell gefördert. Damit sollen insbesondere die Möglichkeiten der parallelen Programmierung ausgebaut werden.[4]

Am 12. Mai 2011 gab Martin Odersky den Start von Typesafe bekannt, ein Unternehmen das sich dem kommerziellen Support von Scala im Allgemeinen sowie dem Middleware Framework Akka widmet. Bemerkenswert ist, dass zu den Beratern Persönlichkeiten wie James Gosling oder Doug Lea gehören. [5]

Konzepte

Integration mit Java[6]

Scala-Programme können Java-JARs ansprechen und umgekehrt. Es können also alle bestehenden Java-Bibliotheken und -Frameworks in Scala-Projekte eingebunden und dort genutzt werden. Ähnliches gilt für die meisten Werkzeuge: 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 erweitern (Schlüsselwort extends).[7] Dabei handelt es sich nicht um Mehrfachvererbung, sondern um einen Mixin-Mechanismus.

Über das Schlüsselwort object (anstelle von class) 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. Auch Funktionen höherer Ordnung[8] sind in Scala realisiert.

Currying

Falls die Signatur einer Methode n Parameterlisten enthält, aber mit nur 1 Parameterliste aufgerufen wird, liefert sie unter Verwendung der übergebenen Parameterliste eine (unbenannte) Methode mit n-1 Parameterlisten zurück.[9]

Siehe auch: Currying

Pattern Matching

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[10] 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.

Siehe auch: Closure

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[11] vorgeben, die von deren Unterklassen in Form konkreter Typen spezifiziert werden müssen. Gleiches gilt für Variablen (var und val) 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: Wenn T Untertyp von U ist, dann ist K[T] Untertyp von K[U]. Kontravarianz, Syntax: K[-T], bedeutet, dass die Fortsetzung in der Gegenrichtung erfolgt: Wenn T Untertyp von U ist, dann ist K[U] Untertyp von K[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.[12]

Typinferenz

Typinferenz ist die Fähigkeit des Compilers den Typ eines Ausdrucks aus dem Kontext herzuleiten, welche unter Syntax beispielhaft dargestellt ist.

Auswertungsstrategie

Funktionale Ausdrücke werden in Scala strikt ausgewertet. Allerdings kann durch das Schlüsselwort lazy die verzögerte Auswertung (Lazy-Evaluation) von einzelnen Ausdrücken spezifiziert werden. Auch die Collection-Klassen unterstützen mit den Methoden view und force die Möglichkeit der verzögerten Auswertung. 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.[13]

Mit impliziten Konversionen wird in Scala auch Verhalten in Bibliotheken implementiert, das viele Sprachen als Spezialfall im Compiler abdecken. So zum Beispiel besondere Regeln beim Zusammenfügen von Zeichenketten wie 42 + "etwas Text" oder die Konvertierung von Zahltypen mit kleinerem Wertebereich zu Zahltypen mit größerem Wertebereich, in Java String concatenation operator +[14] bzw. widening primitive conversions[15] genannt.

Nebenläufigkeit

Während Scala Threads durch die Java-Klassenbibliothek unterstützt, gibt es in Scalas eigener Bibliothek eine Implementierung von Aktoren. Diese wurde von der Aktoren-Implementierung, wie sie in Erlang umgesetzt wurde, inspiriert.

Siehe auch: 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 zur Java-Syntax kann in den meisten Fällen das Semikolon am Ende einer Zeile entfallen. Die Syntax zur Typdefinition von Variablen und Rückgabewerten lehnt sich an der von ML statt von Java an: Man formuliert nicht Typ variable, sondern variable: Typ.

Die Deklaration und Definition von Werten, Variablen und Methoden erfolgt mittels der Schlüsselwörter val, var und def, gefolgt von Typangaben.

    val wert: Int = 42
    var variable: Double = 3.14
    def methode(parameter1: String, parameter2: Boolean): Unit

Der Compiler leitet den Typ einer Variable aus dem Kontext ab (Typinferenz). Die beiden Zeilen

    var x = "Ein Text"

und

    var x: String = "Ein Text"

sind somit gleichwertig.

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")
    List(1,2,3).isEmpty

entspricht

    5.0 + 2.0
    "Test" startsWith "T"
    List(1,2,3) isEmpty

Mit Scala ist es außerdem möglich, den Quelltext im Vergleich zu Java in vielen Fällen kompakter zu schreiben, zum Beispiel auf Grund von Typinferenz, for comprehensions oder anonymen Funktionen.

Operatoren

Für Präfix-Operatoren gibt es eine fest vorgegebene Menge, nämlich +,-,~ und !. Der Ausdruck -x bedeutet das gleiche wie x.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 üblichen Konventionen folgt. Das Codefragment

    1 + z*x

wird übersetzt zu

    (1).+(z.*(x))

Auf dem Objekt 1 wird die Methode + aufgerufen und dabei der Parameter z.*(x), also das Ergebnis eines weiteren Methodenaufrufes, übergeben. Endet der Methodenname eines Infixoperators mit einem Doppelpunkt, so vertauscht sich die Reihenfolge von Empfänger und Parameter und der Operator ist rechtsassoziativ:

    a :: b

wird übersetzt zu

    b.::(a)

Schleifen

For-Schleifen wurden zu sogenannten for comprehensions soweit generalisiert, dass sie nicht nur mehrere verschachtelte Schleifen zusammenfassen, sondern analog zu Haskells do-Notation beliebige Monaden nutzen können.

Dieser Code gibt beispielsweise 27 Zeilen für jeden Wert von a, b und c aus.

for {
    a <- List(1,2,3)
    b <- List(2,3,4)
    c <- List(5,6,7)
} {
    println("a=" + a + ", b=" + b + ", c=" + c)
}

Eine for comprehension kann auch genutzt werden, um neue Werte zu berechnen, ähnlich wie mit den von Python bekannten list comprehensions. Dieser Code weist combinations eine Liste von 4 Paaren zu, nämlich (1,3), (1,4), (2,3) und (2,4):

val combinations = 
        for {
            a <- List(1,2)
            b <- List(3,4)
        }
        yield (a,b)

Versionen

Scala 2.8

Wesentliche Neuerungen im Release 2.8[16] sind:

  • Überarbeitung der Collection-Library (scala.collection)[17]
  • Überarbeitung der Array-Implementierung[18]
  • benannte Argumente und Defaultwerte für Argumente[19]
  • Delimited Continuations
  • Erweiterungen für Aktoren-Nebenläufigkeit
  • Package-Objekte, die Methoden und Werte für ein Package zur Verfügung stellen

Scala 2.9

Die Version 2.9[20] erschien am 12. Mai 2011. Wesentliche Neuerung ist die Erweiterung der Collection-Bibliothek um Methoden und Klassen, die Operationen parallel ausführen können (scala.collection.parallel). Daneben gibt es zahlreiche weitere Verbesserungen:

  • Verbesserungen an der interaktiven Konsole (REPL genannt), die nun u. a. schneller startet, mehr Tastenkürzel und bessere Tastaturnavigation beherrscht und Klassen dekompilieren sowie Typen, Ausnahmebedingungen (Exceptions) und verfügbare implizite Konversionen anzeigen kann.
  • Erweiterung von scala.sys um Möglichkeiten, Anweisungen auf der Shell des Betriebssystems auszuführen.
  • Entfernung einiger als veraltet (deprecated) markierter Klassen und Methoden, wie z. B. in scala.Enumeration und deutlichere Markierung bereits veralteter aber noch nicht entfernter Funktionalität, wie z. B. case-Klassen, die von anderen case-Klassen erben oder der Datenbank-Schnittstelle scala.dbc.

IDEs und Frameworks

Neben dem Compiler scalac steht eine Read-Evaluate-Print-Loop (REPL) namens scala zur Verfügung. Für die IDEs Eclipse,[21] NetBeans[22] und IntelliJ[23] existieren Plugins. Das Framework Lift zur Entwicklung von Web-Applikationen sowie weitere Frameworks[24] 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[25] und Scalaz[26].

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[27].

Verwendung

Die sozialen Netzwerke Twitter und LinkedIn haben ihre Nachrichten-Warteschlangen in Scala implementiert.[28][29]

Scala hat mittlerweile auch Anwendung in der Industrie gefunden. Weitere populäre Verwender sind Novell[30], Siemens, Sony oder Électricité de France Trading.[31]

Siehe auch

Einzelnachweise

  1. Lizenz
  2. Generics in Java
  3. Funnel Homepage
  4. EU fördert Open-Source-Sprache Scala auf dem heise newsticker am 15. Januar 2011, abgerufen am 23. Februar 2011
  5. http://typesafe.com/company/team
  6. Englischsprachige Vorstellung von Scala auf deren offizielles Internetseite
  7. Traits und Mixin Class Composition (englische Erläuterung auf der Scala-Internetseite)
  8. Funktion höherer Ordnung (englische Erläuterung auf der Scala-Internetseite)
  9. Parameterlisten (englische Erläuterung auf der Scala-Internetseite)
  10. Case Classes (englische Erläuterung auf der Scala-Internetseite)
  11. Abstrakte Typen (englische Erläuterung auf der Scala-Internetseite)
  12. Rückgabetyp (englische Erläuterung auf der Scala-Internetseite)
  13. Type classes (PDF)
  14. Java Sprach-Spezifikation, Version 3, §15.18.1, String Concatenation Operator +
  15. Java Sprach-Spezifikation, Version 3, §5.1.2, Widening Primitive Conversion
  16. Release 2.8
  17. Collection-Library
  18. Array-Implementierung
  19. benannte Argumente und Defaultwerte für Argumente
  20. Release 2.9
  21. http://www.scala-ide.org
  22. http://wiki.netbeans.org/Scala
  23. http://plugins.intellij.net/plugin/?id=1347
  24. http://www.scala-lang.org/node/1209#libraries
  25. http://akkasource.org/
  26. http://code.google.com/p/scalaz/
  27. http://code.google.com/p/simple-build-tool/
  28. http://www.artima.com/scalazine/articles/twitter_on_scala.html
  29. http://days2010.scala-lang.org/node/138/159
  30. Novell Vibe
  31. http://www.scala-lang.org/node/1658

Literatur

Weblinks


Wikimedia Foundation.

Игры ⚽ Поможем сделать НИР

Schlagen Sie auch in anderen Wörterbüchern nach:

  • Scala — (ital. scala „Leiter“, „Treppe“) bezeichnet: im Bereich der Kultur: Teatro alla Scala, ein Opernhaus in Mailand Scala (Berlin), eine im Zweiten Weltkrieg zerstörte Varieté Bühne in Berlin Neues Theater in der Scala, ein Wiener Theater der… …   Deutsch Wikipedia

  • Programmiersprache Haskell — Haskell Basisdaten Paradigmen: funktional, nicht strikt, modular …   Deutsch Wikipedia

  • Programmiersprache Java — Java Objektorientierte Programmiersprache Basisdaten Paradigmen: Objektorientierte Programmiersprache Aktuelle  …   Deutsch Wikipedia

  • Haskell (Programmiersprache) — Haskell Basisdaten Paradigmen: funktional, nicht strikt, modular, deklarativ Erscheinungsjahr …   Deutsch Wikipedia

  • Fortress (Programmiersprache) — Fortress Entwickler: Guy L. Steele, Jr. (Sun Microsystems) Aktuelle Version: 1.0 4687  (12. August 2010) wichtige Implementierungen: Interpreter für die Java Plattform Einflüsse …   Deutsch Wikipedia

  • Java (Programmiersprache) — Java Basisdaten Paradigmen: Objektorientierte Programmiersprache Erscheinungsjahr …   Deutsch Wikipedia

  • Smalltalk-80 (Programmiersprache) — Smalltalk Basisdaten Erscheinungsjahr: 1972 (Entwicklung ab 1969) Designer: Alan Kay, Dan Ingalls, Adele Goldberg E …   Deutsch Wikipedia

  • Erlang (Programmiersprache) — Erlang Funktionale Programmiersprache Basisdaten Paradigmen: Funktionale Programmiersprache, Nebenläufige Programmierung …   Deutsch Wikipedia

  • Dart (Programmiersprache) — Dart Paradigmen: Objektorientierte Programmierung Entwickler: The Dart Team Aktuelle Vorabversion: 0.05[1]  (14. November 2011) Typisierung …   Deutsch Wikipedia

  • Nice (Programmiersprache) — Nice ist eine Programmiersprache. Ihre Syntax ähnelt stark der von Java, und zudem erzeugt der Compiler Bytecode für eine Java VM. Im Unterschied zu Java unterstützt Nice eine ganze Reihe von Sprachelementen, die aus der Welt der funktionalen… …   Deutsch Wikipedia

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”