TypeScript? Wozu? Isses wirklich "besser"?
Felix Riesterer
- javascript
Liebe Mitlesende,
heute las ich bei Heise etwas von TypeScript. Da ich mich gerade in C# etwas eingearbeitet habe und mir dort die strenge Typisierung mächtig auf den Senkel geht (wer von PHP/JS kommt, will und braucht sowas nicht!), frage ich mich nun, inwiefern die Welt auf TypeScript nur gewartet hat, oder ob Googles Dart nicht die sinnvollere Idee war... von den bestehenden Frameworks zu JS (oder "Wrappers" wie CoffeeScript oder gar Haxe) einmal ganz abgesehen.
Wer hat dazu eine Meinung, die mir weiterhilft, den Unterschied zwischen Dart, TypeScript und JavaScript zu verstehen und einzuordnen?
Liebe Grüße,
Felix Riesterer.
Hallo Felix,
ich habe da ein interessante Video gefunden.
Es ist von der goto-Conference und dort werden Lars Bak (derzeit Chief Architect von Dart) und Anders Hejlsberg (Chefentwickler für TypeScript) zum Thema "TypeScript, JavaScript, and Dart" interviewed.
Gruß
Ole
Lieber Ole,
ich habe da ein interessante Video gefunden.
herzlichen Dank! Habe es ganz angeschaut und sehe nun wesentlich klarer.
Liebe Grüße,
Felix Riesterer.
Hallo,
TypeScript ähnelt konzeptionell eher CoffeeScript. Es erweitert die JavaScript-Syntax um Typdeklarationen, Klassen, Module, Interfaces… Einiges davon ist auch für ECMAScript 6 oder 7 geplant. TypeScript kompiliert recht nahe zu JavaScript, der Typenkram fällt bei der Kompilierung größtenteils weg. Es gibt also wenig »Magie« und wenig Abstraktion.
Dart ist viel umfangreicher. Es bringt eine komplette Programmierumgebung mit (einen Compiler, ein Interpreter/eine VM, eine Standardbibliothek, eine Entwicklungsumgebung…). Man programmiert üblicherweise abstrahiert mit der Standardbibliothek, weniger direkt mit JavaScript-APIs. Die Bibliotheken schmiegen sich auch ins Ökosystem ein. Der Compiler kann dann natürlich sehr krasse Optimierungen vornehmen und nur den tatsächlich aufgerufenen Code in den Build aufnehmen.
Bei TypeScript verwendet man meist bestehende Libraries, für die muss man dann Typ-Annotationen hinzufügen (z.B. für jQuery), damit man die Vorteile von TypeScript überhaupt nutzen kann.
Dart kann zu JavaScript cross-kompiliert werden. Mit einem gewissen Overhead, weil Code für die Abstraktionen nötig ist. Die Ausgabe des Compilers wird allerdings immer weiter optimiert. Der erzeugte JavaScript-Code hat, soweit ich weiß, wenig mit dem Dart-Code zu tun, gerade weil stark optimiert wird. Eine Zuordnung ist natürlich über Source-Maps möglich, oder durch die Nutzung von Dartium, einem Chromium mit nativer Dart-VM.
Mathias
Mal eine kurze Frage am Rande. Bin ich nur Old School oder dämlich wenn ich sowas wie CoffeeScript nicht benutze? Ich meine, ich komme mit dem üblichen JS inklusive jQuery sehr gut zurecht.
Gruß
old Depp
T-Rex
Mal eine kurze Frage am Rande. Bin ich nur Old School oder dämlich wenn ich sowas wie CoffeeScript nicht benutze? Ich meine, ich komme mit dem üblichen JS inklusive jQuery sehr gut zurecht.
JavaScript ist eine umständliche Sprache mit vielen Bekannten Lücken und Fallstricken. CoffeeScript versucht einiges davon zu korrigeren und vereinfacht die funktionale und objektorientierte Programmierung. Wenn man nur ein bisschen JavaScript hat und sich strenge Regeln und Praktiken auferlegt, kann man JavaScript gut managen. Wenn man große JavaScript-Architekturen hat, wird es viel schwieriger, konsistenten und robusten Code zu schreiben. Dann hilft CoffeeScript (genauso wie TypeScript, Dart oder mit Traceur »transpiliertes« ECMAScript 6) weiter.
jQuery ist eine einfache DOM-Bibliothek und mehr nicht. Größere JavaScript-Anwendungen brauchen eine saubere Architektur, z.B. MVC, Routing, Entkopplung, Modularisierung und Data-Binding. jQuery bietet dazu nahezu nichts und verführt vielmehr zu architekturellen Fehlenscheidungen.
Siehe:
http://molily.de/weblog/javascript-standards zum Einsatz von CoffeeScript und grundlegenden Bibliotheken wie Underscore/Lodash
https://molily.github.io/javascriptdays2014/#/14 zu den Grenzen von jQuery
https://molily.github.io/schulung/#/84 zu MVC und Backbone
</archiv/2013/1/t212358/#m1450390> zu MVC-Bibliotheken
</archiv/2013/5/t213712/#m1461485> zur Trennung von Daten- und View-Logik
</archiv/2014/3/t216771/#m1487278> dito
</archiv/2014/1/t216359/#m1483473> zu Chaplin
Mathias
Wow also mit so einer großen Antwort hätte ich nicht gerechnet, danke!
Bleibt noch die Frage wann du von einer "große JavaScript-Architekturen" sprechen würdest?
Deine Ausführung zum MVC in der JS Welt verstehe ich nicht ganz. Wobei ich verstehe es schon, aber ich sehe kein Einsatzgebiet.
Nehmen wir mal ein einfaches Beispiel.
Ein User hat ein Profil. Das ist in der DB gespeichert. er kommt auf die Seite profil.php und sieht ein Formular mit seinen Daten. Er ändert seinen Namen, drückt auf einen submit Button, das ganze geht wieder an den Server und eine Serverseitige Sprache speichert das ganze ab - das Formular wird erneut geladen.
Da eigentlich nur ein Feld geändert wurde entsteht ein enormer Overhead.
Soweit die ist Situation.
Jetzt will ich die Daten per JS übermitteln. Ich würde diese per jQuery.ajax an ein Serverseitiges Script schicken. Viel Code brauche ich dafür eigentlich nicht. Dort müssten sie aufgefangen und abgespeichert werden. Diesen Part muss ich mittels PHP, PERL oder wie auch immer programmieren. Sehe ich etwas falsch?
Wo kann mir jetzt ein MVC Freundliches Framework helfen?
Gruß
Molily in Beschlag nehmender
T-Rex
Jetzt will ich die Daten per JS übermitteln. Ich würde diese per jQuery.ajax an ein Serverseitiges Script schicken. Viel Code brauche ich dafür eigentlich nicht. Dort müssten sie aufgefangen und abgespeichert werden. Diesen Part muss ich mittels PHP, PERL oder wie auch immer programmieren. Sehe ich etwas falsch?
Das siehst du richtig.
Wo kann mir jetzt ein MVC Freundliches Framework helfen?
Der Fall ist so wahrscheinlich so einfach, dass hier MVC unangebracht ist. Da Daten nur in eine Richtung fließen und nichts groß aktualisiert werden muss, reicht hier eine übliche jQuery-Logik mit 15 Zeilen. Das Formular ist im serverseitig ausgelieferten HTML-Code direkt enthalten, Event-Handler werden per DOM Scripting hinzugefügt, jQuery serialisiert das Formular, schickt es per XHR und zeigt vielleicht noch eine Erfolgsmeldung an. Hier könnte man irgendein komplexeres Framework verwenden, aber es besteht kein zwingender Grund.
In dem besagten Workshop habe ich ein etwas komplexeres Beispiel gezeigt, das sich mit MVC (hier Backbone) besser strukturieren lässt als mit reinem jQuery. Es handelt sich um ein JavaScript-Interface, das aus verschiedenen Komponenten (Views) besteht, Events handelt, Daten verarbeitet, HTML neu rendert.
jQuery-Version
Backbone-Version
Code auf GitHub
Mathias
Liebe Mitlesende,
heute las ich bei Heise etwas von TypeScript. Da ich mich gerade in C# etwas eingearbeitet habe und mir dort die strenge Typisierung mächtig auf den Senkel geht (wer von PHP/JS kommt, will und braucht sowas nicht!)
Sofern man nur alleine arbeitet und der Code nicht allzu umfangreich its (also z.B. nur wenige 1000 Zeilen) ist statische Typisierung nicht nötig oder teilweise sogar störend. Sobald du aber mit mehreren Leuten oder über längere Zeit hinweg oder gar (z.B. in Weltkonzernen) mit verschiedenen Teams in verschiedenen Ländern und Zeitzonen zusammenarbeit musst, wird es _unglaublich_ schwierig, ohne statische Typisierung klarzukommen.
Hallo,
Ich entwickle seit Jahren in Ruby und JavaScript. Beide haben ein riesiges Open-Source-Ökosystem, das von Entwicklern weltweit gepflegt wird. Dasselbe gilt für Anwendungen, die in Ruby und JavaScript geschrieben sind. Es ist nicht so, als würden diese Sprachen nur Anwendungen mit 1000 Zeilen oder wenigen Entwicklern erlauben, oder als litte die Produktivität notwendig gegenüber statisch typisierten Sprachen. Es kann sein, dass die Entwicklung irgendwann »unglaublich schwierig« wird, aber das liegt eher an den Nebeneffekten und Defiziten, die die meisten dynamischen Sprachen mit sich bringen. I got 99 problems, but dynamische Typisierung ain’t one.
Was TypeScript angeht, so habe ich ja beschrieben, wie schlecht es sich erst einmal in das Ökosystem einschmiegt. Es ist ein Haufen Arbeit nötig, um halbwegs vollständige Typannotationen zu bekommen, damit man Compilezeit-Warnungen bekommt und die Vorzüge einer IDE genießen kann, die den Code und die Typen sämtlicher Werte versteht. In der gleichen Zeit könnte man mit JavaScript/CoffeeScript mit JSDoc/code Typannotationen hinzufügen. Heutige JavaScript-IDEs und -Lints sind bereits sehr mächtig. Es gibt etliche Lösungen, z.B. den Google Closure Compiler. Da finde ich Darts Ansatz schon schöner, nur bin ich noch stärker vom JavaScript-Ökosystem abgekoppelt.
Grüße
Mathias
Hallo,
Ich entwickle seit Jahren in Ruby und JavaScript. Beide haben ein riesiges Open-Source-Ökosystem, das von Entwicklern weltweit gepflegt wird. Dasselbe gilt für Anwendungen, die in Ruby und JavaScript geschrieben sind. Es ist nicht so, als würden diese Sprachen nur Anwendungen mit 1000 Zeilen oder wenigen Entwicklern erlauben, oder als litte die Produktivität notwendig gegenüber statisch typisierten Sprachen.
Wieviele Zeilen Code hast du mit wieviel anderen bisher in deinem größten projekt geschrieben?
Es kann sein, dass die Entwicklung irgendwann »unglaublich schwierig« wird, aber das liegt eher an den Nebeneffekten und Defiziten, die die meisten dynamischen Sprachen mit sich bringen.
man kann natürlich auch mit solchen Sprachen große Projekte machen, aber nach meiner Erfahrung leidet die Produktivität deutlich. wobei ruby eine schöne Sprache ist (die zweitbeste die ich kenne) und natürlich viel entschärft, im Gegensatz zu js.
Hallo,
Wieviele Zeilen Code hast du mit wieviel anderen bisher in deinem größten projekt geschrieben?
Die Firma, für die ich arbeite, macht hauptsächlich angepasste Webanwendungen. Die haben (ich hoffe, ich habe das richtig im Kopf) höchstens 10-20 KLOC Ruby, dazu kommen ein großer Haufen HAML, Sass, CoffeeScript sowie Logik in anderen Sprachen (z.B. Shell). Webanwendungen mit hauptsächlich clientseitiger Dynamik haben > 10 KLOC CoffeeScript. Darunter liegt natürlich immer ein umfangreicher Stack an Bibliotheken (Node-/Bower-Module bzw. RubyGems). Die Teams sind nicht groß, maximal 6 Entwickler, würde ich schätzen.
Ich will das gar nicht als Maßstab nehmen. Dass Ruby in dem Fall funktioniert, steht nicht infrage. Aber bekanntermaßen gibt es aber viel größere Ruby- und JavaScript/Node-Anwendungen (z.B. GitHub) mit Teams, die auf der Welt verteilt sind. Gründe, von Ruby weg zu migrieren, sind eher die schlechte Performance und Skalierbarkeit.
Mathias
wer von PHP/JS kommt, will und braucht sowas nicht!
Interessante Meinung! Ich finde vielmehr wer programmieren will statt Fehler suchen und raten was wohl vielleicht passieren könnte, der braucht das unbedingt.
Ich frage mich seit ich mich mit PHP beschäftige, wie so eine schlampige fehlerträchtige Sprache es zum Webstandard geschafft hat. Gerade in einer Umgebung wo man nicht so einfach debuggen kann sondern sich mit Kontrollausgaben usw. behelfen muss, bis man endlich merkt dass eine Variable nicht als Zahl behandelt wird sondern als String (oder andersrum) und deswegen gerade nichts geht.
Ein gescheiter Compiler sagt einem dass man unverträgliche Datentypen hat, da läuf man gar nicht erst in die Gefahr etwas zu vermurksen.
Lieber Encoder,
wer von PHP/JS kommt, will und braucht sowas nicht!
Interessante Meinung! Ich finde vielmehr wer programmieren will statt Fehler suchen und raten was wohl vielleicht passieren könnte, der braucht das unbedingt.
meine Aussage rührt von meinen eigenen Erfahrungen mit meinem Hobby her. Mittlerweile ist in diesem Thread genügend darauf hingewiesen worden, dass allein die Größe und Komplexität einer Webanwendung entscheidet, ob auf statische Typisierung zugunsten von dynamischer Typumwandlung verzichtet werden kann.
Offensichtlich sind meine Projekte klein genug, dass es mir lieber ist, manches in einem Einzeiler notieren zu können, als "sauber" und typsicher zu schreiben. Beispiel aus einem C#-Projekt von mir:
public bool IsCorrectAnswer (string a) {
bool r = false;
if (a == this.CorrectAnswer) {
r = true;
}
return r;
}
Wie liebe ich es doch in PHP stattdessen schreiben zu dürfen:
public function is_correct_answer (a) {
return (a == this.correct_answer);
}
Je nachdem wie aussagekräftig Methoden und Variablen/Eigenschaften benannt sind, konnte ich auf Debug-Ausgaben hinsichtlich Typenbehandlung verzichten. Meine Ausgaben haben vielmehr Ergebnisse von String-Operationen zum Inhalt.
Ein gescheiter Compiler sagt einem dass man unverträgliche Datentypen hat, da läuf man gar nicht erst in die Gefahr etwas zu vermurksen.
Hmm. Das bedeutet ja, dass man für "große" Projekte (wie bsp. ein OS) eine statisch typisierende Sprache benötigt, während dynamisch typumwandelnde Sprachen für "kleine" Projekte besser geeignet wären. Wo siehst Du jetzt das Problem? Dass wegen des "Standards PHP" große Projekte mit einer ungeeigeneten Sprache umgesetzt werden sollen/müssen?
Liebe Grüße,
Felix Riesterer.
Hallo Felix,
Offensichtlich sind meine Projekte klein genug, dass es mir lieber ist, manches in einem Einzeiler notieren zu können, als "sauber" und typsicher zu schreiben. Beispiel aus einem C#-Projekt von mir:
public bool IsCorrectAnswer (string a) {
bool r = false;
if (a == this.CorrectAnswer) {
r = true;
}return r;
}
>
> Wie liebe ich es doch in PHP stattdessen schreiben zu dürfen:
>
> ~~~php
public function is_correct_answer (a) {
> return (a == this.correct_answer);
> }
zu C# kann ich nichts sagen - aber diese kurze, bequeme Schreibweise, die du für PHP als Beispiel nennst, ist in C völlig normal und korrekt. Denn a==b
ist ein Ausdruck, der aus dem Operator == und zwei Operanden besteht, und der per definitionem einen Wert ungleich 0 liefert (meist 1, das ist aber nicht festgelegt), wenn die Operanden gleich sind, und 0, wenn sie es nicht sind. Selbst im strengen Pascal ist dieses Konstrukt erlaubt - ich kann mir daher nicht vorstellen, dass das in C# nicht so sein sollte.
Hmm. Das bedeutet ja, dass man für "große" Projekte (wie bsp. ein OS) eine statisch typisierende Sprache benötigt, während dynamisch typumwandelnde Sprachen für "kleine" Projekte besser geeignet wären.
Nein, das würde ich so nicht sagen. Ich stimme zwar zu, dass eine Sprache mit fester Typisierung hilft, Fehler zu vermeiden und daher für große Projekte eventuell besser geeignet ist, aber ich sehe umgekehrt bei kleinen Projekten nicht wirklich einen Vorteil von lockerer Typisierung.
Ciao,
Martin
Hallo,
Ein gescheiter Compiler sagt einem dass man unverträgliche Datentypen hat, da läuf man gar nicht erst in die Gefahr etwas zu vermurksen.
Das bedeutet ja, dass man für "große" Projekte (wie bsp. ein OS) eine statisch typisierende Sprache benötigt, während dynamisch typumwandelnde Sprachen für "kleine" Projekte besser geeignet wären.
Das würde ich so pauschal nicht sagen. Es werden auch Projekte mit hunderttausenden Zeilen Code in dynamischen Sprachen geschrieben. Es gibt auch riesige Projekte in typsicheren Sprachen, die vermurkst sind. Typisierung ist sicher eine Komponente. Mit vernünftigen Frameworks, Bibliotheken, QA-Tools und IDEs, mit Test-Driven Development sind auch dynamische Sprachen umgänglich und verlieren nicht an Expressivität.
Mathias
Wie liebe ich es doch in PHP stattdessen schreiben zu dürfen:
public function is_correct_answer (a) {
return (a == this.correct_answer);
}
Probiers mal in C# auch so ;-)
> Hmm. Das bedeutet ja, dass man für "große" Projekte (wie bsp. ein OS) eine statisch typisierende Sprache benötigt, während dynamisch typumwandelnde Sprachen für "kleine" Projekte besser geeignet wären. Wo siehst Du jetzt das Problem? Dass wegen des "Standards PHP" große Projekte mit einer ungeeigeneten Sprache umgesetzt werden sollen/müssen?
Ungeeignet scheint es ja nicht zu sein, sonst würden es nicht so viele machen. Ich find nur schade dass es keine Option für typisiertes Programmieren gibt.
Ich weiß das ist alles Glaubenskrieg, da muss man nicht versuchen jemanden zu bekehren! Als jemand der Typisierung schätzt geht mir PHP eben zu sehr in die Richtung: mach mal drauf los, du kannst versuchen alles überall reinzustecken und auszulesen, \*irgendwas\* wird schon passieren. Mit viel Glück das richtige, mit etwas weniger Glück gibts immerhin eine Warning. Vielleicht merkst du aber auch lange nicht dass nicht das erwartete passiert, dann hast du halt Pech gehabt.
Ich kenne C# und habe da auch schon "große" Dinge gemacht. Da ist es (für mich) unverzeichtbar wenn IDE und Compiler mir bereits sagen können ob es eine Variable überhaupt gibt, welchen Typ sie hat, welche Eigenschaften sie hat, oder mir sagen kann hey es gibt hier keine Eigenschaft namens "coment" weil ich ein m vergessen habe - was ja alles nur geht wenn der Typ feststeht.
In PHP gibt es höchstens eine Warnung. Wenn man Pech hat wird mit .coment einfach nichts ausgegeben, obwohl .comment seitenweise Inhalt hätte.
Oder: Hab ich jetzt eine Zahl oder einen String? Kann ich das so ausgeben oder muss ich es formatieren? Kann ich damit rechnen weil gilt 2 \* 5.5 = 11 oder steht noch 5,5 (mit Komma) drin und bei der Berechnung zählt das als 55 oder als gar keine gültige Zahl?
Nach den Fehlern die ich wegen fehlender Typisierung bereits in ganz simplen Freizeit-Spielereien mache, würde ich was größeres nie im Leben in PHP machen wollen.
Als jemand der Typisierung schätzt geht mir PHP eben zu sehr in die Richtung: mach mal drauf los, du kannst versuchen alles überall reinzustecken und auszulesen, *irgendwas* wird schon passieren.
Du könntest ja Hack schreiben. ;) PHP mit Typangaben.
Da ist es (für mich) unverzeichtbar wenn IDE und Compiler mir bereits sagen können ob es eine Variable überhaupt gibt, welchen Typ sie hat, welche Eigenschaften sie hat, oder mir sagen kann hey es gibt hier keine Eigenschaft namens "coment" weil ich ein m vergessen habe - was ja alles nur geht wenn der Typ feststeht.
Naja… Solche trivialen Dinge kann jede halbwegs gute PHP-IDE. Typinferenz ist auch bei dynamisch typisierten Sprachen möglich.
$foo = new Bar();
$foo->quux();
Jede gute PHP-IDE weiß hier, dass $foo eine Variable vom Typ Bar ist. Sie liest die Klassendeklaration von Bar ein, sucht »quux« in den dort deklarierten Methoden und zeigt ggf. eine Warnung an.
Das ist jetzt ein triviales Beispiel, aber heutige Typinferenz-Algorithmen sind äußerst leistungsfähig.
Hab ich jetzt eine Zahl oder einen String? Kann ich das so ausgeben oder muss ich es formatieren? Kann ich damit rechnen weil gilt 2 * 5.5 = 11 oder steht noch 5,5 (mit Komma) drin und bei der Berechnung zählt das als 55 oder als gar keine gültige Zahl?
Das ist weniger eine Frage von statischer vs. dynamischer Typisierung, sondern von starker vs. schwacher Typisierung. Oder auch einfach gutem vs. schlechtem Sprachdesign. ;)
Natürlich ist PHP hinsichtlich Operatoren, Typecasting und Fehler grässlich, auch JavaScript hat viele Fallstricke. Andere dynamisch typisierte Sprachen sind da strenger:
$ php -r "echo 2 * '5.5';"
11
$ node -e "console.log(2 * '5.5');"
11
$ ruby -e "puts 2 * '5.5';"
-e:1:in \*': String can't be coerced into Fixnum (TypeError) from -e:1:in
<main>'
$ ruby -e "puts 2 * '5.5'.to_f;"
11.0
$ ruby -e "puts '5.5' * 2;"
5.55.5
$ python -c "print 2 * '5.5'"
5.55.5
Dass ein Komma im String sein kann, musst du in sämtlichen Sprachen antizipieren, sonst kommt ggf. unerwünschtes heraus:
$ php -r "echo floatval('5,5');"
5
$ ruby -e "puts '5,5'.to_f;"
5.0
$ node -e "console.log(Number('5,5'));"
NaN
$ node -e "console.log(parseFloat('5,5'));"
5
$ python -c "print float('5,5')"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ValueError: invalid literal for float(): 5,5
Die Regeln der Umwandlung von String in Floats sind in allen Sprachen dokumentiert und vorhersehbar.
Mathias
Hallo
Ich weiß das ist alles Glaubenskrieg, da muss man nicht versuchen jemanden zu bekehren! Als jemand der Typisierung schätzt geht mir PHP eben zu sehr in die Richtung: mach mal drauf los, du kannst versuchen alles überall reinzustecken und auszulesen, *irgendwas* wird schon passieren. Mit viel Glück das richtige, mit etwas weniger Glück gibts immerhin eine Warning. Vielleicht merkst du aber auch lange nicht dass nicht das erwartete passiert, dann hast du halt Pech gehabt.
Ja, PHP verleitet zum „mach mal drauf los“ ohne viel zu planen. Ja, viele Skripte werden von ihren Entwicklern nicht mal mit eingeschaltetem Error Reporting geschrieben, so dass sehr oft gerade Logikfehler aufgrund der schwachen Typisierung nicht sofort auffallen. Größere Fehler fallen eher auf. Sie schlagen hier gerne mit „ich hab nur eine weiße Seite“ auf.
ABER niemand ist *gezwungen*, in PHP unsauber zu programmieren. Ich kann alle Variablen explizit deklarieren. Ich kann Variablen mit festen Typen benutzen, typsicher vergleichen und den Typ einer Variablen bei Bedarf bewusst ändern. Das muss ich als Entwickler aber bewusst und akribisch durchziehen.
An der Stelle wäre eine im Skript anzugebende Einstellung wie strict bei Perl hilfreich, die den Level des Error Reporting anpasst und so zur Einhaltung der Regeln zwingt.
Tschö, Auge