D hat ja den Anspruch "C++ done right" zu sein und abgesehen vom bescheuerten Namen
haben sie die letzten zwanzig Jahre Erfahrung bei der Nutzung von Programmiersprachen
auch sichtlich niedergeschlagen. Leider fehlt offensichtlich Manpower, sodass
einige Features immer noch unausgegoren sind.
Die Syntax. Was gefällt mir:
Mit der Syntax wurde aufgeräumt. Arrayliterale werden mit [ ] eingeschlossen.
Funktionpointer werden über die Schlüsselwörter function und delegate definiert,
anstatt der mehr als kruden Syntax aus C++, die ich immer nachschlagen muss.
Template-Argumente werden nicht in < > eingeschlossen, sondern in !( ). Daran
muss man sich gewöhnen, danach ist es aber ebenso gut lesbar. Jedenfalls besser
als das Geplänke > > > in C++03. Bei der Definition von Templates kann man die Templateparameter
bei Klassen und Funktionen einfach hinten anhängen:
class TemplatedClass(T, U)
{
T u;
U t;
}
Es gibt eine foreach-Schleife und man kann eigene Typen so erweitern, dass eine Iteration
mit foreach über sie möglich ist. Genauso wie in C++11 kann man Enumerations so
schreiben, dass sie einen Namensraum eröffnen. Ach ja, und es gibt Slices für eingebaute
Arrays.
Was gefällt mir nicht? Eigentlich nichts. Die Syntax ist gut überlegt. Ich
lese ein bisschen auf der Maillingliste mit und manchmal kommen Vorschläge
für Spracherweiterungen, die dann die C-Syntax an ihre Grenzen bringen würden.
Das einzige, was mich manchmal verwirrt, sind lambda-Funktionen. Die Syntax ist
[function|delegate] ( [params] ) { body }. Also zum Beispiel
function int (int a, int b) { return a + b; }. Aber auch einfach
(int a, int b) { return a + b; }. Wenn sowas alleine steht, ist das in Ordnung. Wenn
das als Parameter eines Funktionsaufrufs vorkommt, haben die ganzen Klammern der
C-Syntax IMO die Eigenschaft den Code ein wenig zu vernebeln.
Eingebaute Datentypen / Grundlegende Sprachfeatures.
Was gefällt mir? Eingebaute dynamische Arrays mit Slicing und (optionalem)
Bound-Checking. Sowas darf heutzutage echt in keiner Sprache fehlen. Außerdem
gibt es Assoziative Arrays als eingebaute Typen - nice. Alle eingebauten Typen haben
wohl definierte Wertebereiche. Das sollte der Portabiblität gut tun.
Unterstützung von Delegates und anonymen Funktionen. Unterstützung von Arrayoperationen.
Code: Alles auswählen
int[] a = [1, 1, 1];
int[] b = [2, 2, 2];
int[] c[] = a[] + b[];
// c ist [3, 3, 3];
Es gibt drei Typen für Chars (char, wchar, dchar), in 8, 16 und 32 Bit. Die stehen für Unicode-Character in UTF-X. Strings sind damit
einfach immutable(char)[] etc. Iteriert man über einen String in char (8 bit), bekommt man keine halben Codepoints geliefert.
Es gibt immutable und const als Typspezifizierer. Const = ich darf nichts ändern (und zwar transitiv) und immutable bedeutet,
dass der Compiler erzwingt, dass niemand eine Variable ändert. Ob das gut oder schlecht ist, kann ich noch nicht beurteilen.
Der größte Potenzial, dass ich in D sehe, ist aber die Fähigkeit Code zur Übersetzungszeit zu generieren und auszuführen und
eine gute Compile-Time-Introspection. Einer hat damit eine Bibliothek für Serializing geschrieben, die fast vollständig
ohne Angaben vom Nutzer auskommt. Einfache eine Datenstruktur reinstecken und der speichert sie und liest sie wieder ein.
Man muss nur eine Zeile extra schreiben, wenn man Subklassen durch Referenzen auf Basisklassen serialisieren will.