Derzeit vorherrschende Sprachen wie C, C++, Java, Perl oder Python sind imperativ-objektorientiert. In diese Kategorie fällt auch die etwas exotische Sprache D[1]. Der Name deutet es an: D ist als Nachfolgerin von C konzipiert, sie soll mit deren Unzulänglichkeiten aufräumen und dabei effizienter und leichter zu erlernen sein als C++. Walter Bright - Autor von D - charakterisiert seine Entwicklung als System- und Applikationssprache, die zwar auf einem höheren Level als C++ angesiedelt ist, sich aber auch für Low-Level-Aufgaben wie Kernelprogrammierung eignet.
Stärken und Schwächen
Eine große Schwäche von D ist die mangelnde Unterstützung durch Werkzeuge. Die Standardbibliothek ist - selbst nach Aussage des Autors - arg unterentwickelt. Für die GUI-Entwicklung auf Linux existiert lediglich eine Alphaversion des GTK-Bindings DUI ([3] und Abbildung 1). Debugger und Code-Browser sind zumindest für Linux nicht vorhanden. Diese Vernachlässigung teilt D mit einer Reihe anderer Sprachen. Dass es auch anders geht, beweisen Implementierungen für Smalltalk, Common Lisp, Scheme, Erlang oder Beta.
Abbildung 1: DUI gibt D-Programmierern Zugriff auf die GTK-Widgetbibliothek. Allerdings ist DUI erst im Alphastadium, mehr als solche Testprogramme sind derzeit kaum zu erwarten.
Einfach zu lernen ist D vor allem für C- und C++-Programmierer. Auf den ersten Blick sieht ein D-Programm wie C aus (siehe Listing 1). Kompilieren lässt sich das Beispiel mit dem DMD-Compiler[2]: »dmd greetings.d«. Der Aufruf »./greetings Hallo Leser« führt zu folgender Ausgabe:
args[0] = './greetings'
args[1] = 'Hallo'
args[2] = 'Leser'
Näher betrachtet zeigt jedoch schon die Deklaration der »main()«-Funktion, dass es sich nicht um C handelt. Die Notation »[]« steht für ein dynamisches Feld, in dem implizit die Länge vorliegt. Ähnliches ist zwar auch in C möglich, dort aber nur für eindimensionale Felder.
Zu den wichtigen Neuerungen von D gegenüber C zählen Klassen, Schnittstellenbeschreibungen (Interfaces), Schablonen (Templates), die strukturierte Fehlerbehandlung (Exceptions) und die automatische Speicherverwaltung (Garbage Collection). Von Eiffel entlehnt D das Design by Contract. Überladen von Funktionen ist gestattet. Ähnlich wie Java (aber im Gegensatz zu C++) kennt das Klassenkonzept von D zwar nur Einfachvererbung, mit Interfaces lässt sich die Mehrfachvererbung aber nachbilden. Das Beispiel in Listing 2 verwendet Interfaces, Klassen, Vererbung und teilweise Design by Contract.
01 int main(char[][] args) {
02 for (int i = 0; i < args.length; i++)
03 printf("args[%d] = '%s'n", i, (char *)args[i]);
04 return 0;
05 }
|
Klassendeklaration
Der Code in Zeile 9 deklariert eine Klasse, die zwei Interfaces implementiert (Zeilen 1 und 5). Wenn eine Klasse von einer Schnittstelle abgeleitet wird, muss sie alle in der Schnittstelle vorliegenden Funktionen implementieren. Java-Programmierer kennen dieses Konzept, auch ihre Sprache nutzt Interfaces. Das Beispiel leitet weitere geometrischen Figuren von »Figure« ab (Circle, Rectangle und Triangle).
Die Implementierung der Klasse »Rectangle« (Zeile 15 bis 48) zeigt einige wichtige Sprachkonzepte. Die Klassendeklaration ist der von C++ sehr ähnlich. Nach dem Schlüsselwort »class« folgen der Klassenname, ein Doppelpunkt »:«, die Superklasse sowie eine oder mehrere Schnittstellenbeschreibungen (Zeile 15). Die »import«-Anweisung (Zeile 16) lädt zusätzliche Module. Diese spannen einen eigenen Namensraum auf und vermeiden so Probleme, die bei einem globalen Namensraum auftreten. Namenskollisionen lassen sich leicht auflösen, indem man der Funktion den Modulnamen voranstellt.
D unterscheidet bei den Zugriffsrechten zwischen »private«, »protected«, »public« und »export«. Als »private« deklarierte Elemente sind nur innerhalb der Klasse sichtbar. Für »private«-importierte Module gilt diese Sichtbarkeitsregel ebenfalls, ihre Funktionen werden kein Bestandteil der Schnittstelle der sie importierenden Klasse. Die Zeilen 19 und 20 deklarieren zwei private Felder der Klasse, hier die beiden Seiten eines Rechtecks. Auf exportierte Symbole (Schlüsselwort »export«) können auch Programme außerhalb des entwickelten Systems zugreifen. Nützlich ist das vor allem beim Erstellen von dynamischen Bibliotheken.
Neue Objekte lassen sich mit »new Klassenname« erzeugen. Standardmäßig verwendet D Garbage Collection, Objekte explizit freigeben ist daher nicht nötig. Die Konstruktoren tragen den Namen »this« (Zeilen 26 und 31). Da das Überladen von Funktionen erlaubt ist, kann eine Klasse viele Konstruktoren erhalten, die sich im Typ ihrer Argumente unterscheiden.