Mein erster Eindruck von Dart war: Enttäuschend. Ich hatte mir mehr erhofft. Radikaler, neuer, etwas, das in 2011 passt und nicht wie 1995 aussieht. Also nicht einfach nur Java mit einem optionalen Typsystem.
Da man ja mit etwas positivem beginnen soll, bevor man kritisiert:
http://try.dartlang.org/ finde ich ziemlich gut als Idee. An dem optionalen Typsystem, welches absichtlich nicht "sound" ist, habe ich auch nichts auszusetzen. Meine Erfahrung zeigt, dass man ansonsten immer bei etwas wie Scala landet und das ist so schwergewichtig, dass es den Preis nicht wert ist. Ich bin da völlig bei den Leuten, dass die Typen Dokumentation und Tool-Unterstützung verbessern sollen, aber nicht notwendig sind, um die Sprache schnell zu machen (das ist ein Mythos, den bereits ein Paper von 1995 oder so aus dem Self-Projekt widerlegen konnte).
Ich kann jedoch nicht verstehen, wieso eine moderne Sprache ihre Zeilen mit ";" beenden muss. Das Zeilen zu lang werden können, ist bitte ein Problem, was das Tooling lösen kann. Xcode bricht etwa lange Zeilen automatisch um: Problem gelöst. Das { } statt Einrückung für Blöcke benutzt wird, kann ich noch eher verstehen, weil sich derartiger Quelltext in Webseiten besser einbinden lässt. Und wenn ich in diesem Kontext mehr als eine Anweisung in eine Zeile quetschen will, dann in Gottes Namen auch ein ";", aber ansonsten...
Warum es aber keine Mehrfachzuweisungen oder List-Comprehensions gibt, verstehe ich nicht. Auf generelles Pattern Matching will ich ja gar nicht hoffen. Ansonsten sind es viele Kleinigkeiten: Muss es wirklich "static final" statt "const" sein? Warum ist das, was eigentlich der Standard sein sollte, "final" für Variablen, länger und umständlicher und hässlicher, als "var". Ich finde, hier hat Scala mit "val" und "var" es richtig gemacht. Das hätte natürlich erfordert, dass man Typen hinter die Variablennamen schreibt und das wollten sie wohl nicht, weil so die IDE nicht aus dem Typ einen Variablennamen vorschlagen kann. Andererseits: Will man das wirklich, was für Informationen bringt mir ein "Person person = new Person()"? Auch gefällt mir die Idee von Scala, neben "class" noch "object" zu haben, um Singletons zu definieren und gleichzeitig "static" aus der Sprache zu verbannen. Die Traits von Scala (und Self) hätte ich natürlich auch gerne gehabt. Und bitte die impliziten Interfaces von Go. Das ist IMHO die eine großartige Neuerung dieser Sprache, die es verdient, in jede andere aufgenommen zu werden. Statt Klassen-Objekte "callable" zu machen und auf "new" als Schlüsselwort zu verzichten, erfindet man lieber komische factory-Pattern in der Sprache und hat eine IMHO umständliche Konstruktor-Syntax. Alternativ hätte mir auch der Weg von Smalltalk, Objective-C und Ruby gefallen, dass man Klassenmethoden hat und dann eben "Person.new()" aufruft, um eine Person zu erzeugen.
Schade ist auch, dass Dart nicht JSON-kompatibel ist und es keines alternatives Serialisierungsmodell in der Sprache gibt. C# oder JavaFX (als es noch eine Sprache war) haben da IMHO eine schöne Syntax gefunden. Allgemein: Ein Weg, optionale Schlüsselwortparameter bequem typisieren zu können, wäre hilfreich.
Ich störe mich auch daran, dass es "num" und "String" gibt, nicht aber "Number" und "String" oder meinetwegen "num" und "str", aber jedenfalls bitte (!) alle Typen gleichartig benennen. Das hat Python schon verkorkst und auch bei Scala hat es gedauert, bis man sich dann auf alles beginnt mit einem Großbuchstaben geeinigt hat.
Wenn man schon ein Schlüsselwort "operator" braucht, um nicht-alphanumerische Methodennamen zu definieren, warum kann man dann nicht mit "operator eur(x)" auch mal einen Postfix-Operator für Währungen oder so definieren. Will sagen, die Sprache ist mir nicht ortogonal genug.
Und das ist eine "NullPointerException" gibt, ist ja wohl ganz großes Kino. Was soll der Scheiß? Hat man bei Java nicht schon gelernt, dass es keine "Pointer" in dieser Sprache gibt und "NullReference" oder "MissingObject" oder irgendwas anderes außer Null Pointer ein besserer Name wäre? Warum ist null überhaupt standardmäßig erlaubt? Standardmäßig würde ich ja erwarten, dass null nicht Teil eines Typs ist und man einen spezielle Vereinigungstyp "Foo | Null", meinetwegen als "Foo?" geschrieben braucht, um eine Variable zu definieren, die beides enthalten kann. Vereinigungstypen gehören IMHO eh in ein gutes Typsystem, denn häufig will man gerade im JavaScript-Umfeld (man schaue sich nur mal Jquery oder Ext an) verschiedene Typen verarbeiten können, die auch nicht die selben Enten sind.
Klar, Bracha und Bak (und die anderen, die an Dart arbeiten), können vieles noch ändern, aber wie gesagt, meine Erwartungen waren höher: Ich dachte, es ist ausgereifter und enthält neue Ideen statt einfach nur ein Java oder besser noch ActionScript-Clone zu sein. Da können sie auch gerne schon mal eine IDE basierend auf Eclipse gebaut haben oder eine eigene VM, die vielleicht sogar auf mobilen Geräten läuft. Wenn die Sprache nicht stimmt, ist mir das egal. Die Sprache zeigt IMHO die Vision und die ist ernüchternd: Wieso sollte man Dart benutzen, wenn es nicht wirklich oder nur marginal besser ist als Java, JavaScript, ActionScript usw. Das ist das gleich Problem wie mit Python 3. Das ist auch nicht besser gut im Vergleich zu Python 2.
Wo ist die Vision, dass man mit Dart z.B. in einer Sprache Server und Client-seitig arbeiten kann. Das sie auf dem Client in JavaScript kompilieren können, ist klar. Sever-seitig wäre es ein leichtes, in Java bzw. JVM-Bytecode zu übersetzen. Doch das wäre keine Priorität, sagt Bracha in der Mailing-List. Dabei wäre das eine Produkt-Strategie. Und genau diese sehe ich nicht klar formuliert. Ein "mal gucken, was passiert" ist mir zu wenig.
Stefan
PS: Diesen Schwachsinns-gist (inklusive der genauso sinnlosen Diskussion in den Kommentaren) der zeigt, dass Dart zur Zeit offenbar seine komplette Laufzeitbibliothek an jedes Programm anhängt, kommentiere ich nicht weiter. Das sich dieses leicht abstellen liesse, muss doch nicht weiter erwähnt werden.