Dynamische Typsprachen versus statische Typsprachen

205

Was sind die Vor- und Nachteile dynamischer Typensprachen im Vergleich zu statischen Typensprachen?

Siehe auch : Was ist mit der Liebe zu dynamischen Sprachen (ein weitaus argumentativerer Thread ...)

cvs
quelle
10
Diese Frage ist zu subjektiv.
Jason Dagit
7
Ich würde es nicht subjektiv nennen, sondern Flammenköder. Es gibt jedoch einige objektive Fakten dazu.
Vinko Vrsalovic
2
Einverstanden: zu subjektiv. Es ist interessant, die beiden Ansätze zu vergleichen und gegenüberzustellen, aber es schwankt gefährlich am Rande der Forum-Apokalypse.
Daniel Spiewak
17
Dynamische Sprachen eignen sich hervorragend für die schnelle Entwicklung von Demo- / Wegwerfanwendungen. Wenn Sie einen Tippfehler machen, der Sie interessiert, wird die Webseite immer noch geladen. Möglicherweise sind hier oder da nur einige Datenelemente falsch. Ich kann mir keine andere Situation vorstellen, in der die Möglichkeit, Ihre Variablen falsch einzugeben, ohne einen Compilerfehler zu erhalten, als "Vorteil" angesehen wird.
Alex R
4
Ein solcher Fehler würde JavaScript normalerweise zum Stillstand bringen, was ich für eine sehr gute Sache halte. Zumindest würde es Fehler werfen, die ich auch wertvoll finde. Aus irgendeinem Grund ist es immer ein Typ aus einem statischen Tippparadigma, der seine Javascript-Fehler mit leeren try / catch-Anweisungen begraben möchte. Nach meiner Erfahrung war es so etwas wie ein Phänomen. Was ist das? Unabhängig davon ist es nicht so, dass wir kein Feedback erhalten, wenn wir unseren Code ausführen.
Erik Reppen

Antworten:

139

Die Fähigkeit des Interpreters, Typ- und Typkonvertierungen abzuleiten, beschleunigt die Entwicklungszeit, kann aber auch Laufzeitfehler hervorrufen, die in einer statisch typisierten Sprache, in der Sie sie zur Kompilierungszeit abfangen, einfach nicht auftreten können. Aber welches besser ist (oder auch wenn das immer stimmt), wird heutzutage (und seit langer Zeit) in der Community heiß diskutiert.

Eine gute Sicht auf das Problem ist die statische Typisierung, wo möglich, die dynamische Typisierung bei Bedarf: Das Ende des Kalten Krieges zwischen Programmiersprachen von Erik Meijer und Peter Drayton bei Microsoft:

Befürworter der statischen Typisierung argumentieren, dass die Vorteile der statischen Typisierung die frühere Erkennung von Programmierfehlern (z. B. das Verhindern des Hinzufügens einer Ganzzahl zu einem Booleschen Wert), eine bessere Dokumentation in Form von Typensignaturen (z. B. das Einbeziehen von Anzahl und Arten von Argumenten beim Auflösen von Namen) umfassen Möglichkeiten für Compiler-Optimierungen (z. B. Ersetzen virtueller Aufrufe durch direkte Aufrufe, wenn der genaue Typ des Empfängers statisch bekannt ist), erhöhte Laufzeiteffizienz (z. B. müssen nicht alle Werte einen dynamischen Typ enthalten) und eine bessere Erfahrung der Entwickler bei der Entwurfszeit (z. B. Wissen) Je nach Typ des Empfängers kann die IDE ein Dropdown-Menü aller zutreffenden Mitglieder anzeigen. Statische Tippfanatiker versuchen uns glauben zu machen, dass „gut typisierte Programme nichts falsch machen können“. Während dies sicherlich beeindruckend klingt, es ist eine ziemlich leere Aussage. Die statische Typprüfung ist eine Abstraktion des Laufzeitverhaltens Ihres Programms zur Kompilierungszeit und daher notwendigerweise nur teilweise solide und unvollständig. Dies bedeutet, dass Programme aufgrund von Eigenschaften, die nicht von der Typprüfung verfolgt werden, immer noch schief gehen können und dass es Programme gibt, die zwar nicht schief gehen können, aber nicht typgeprüft werden können. Der Impuls, die statische Typisierung weniger partiell und vollständiger zu gestalten, führt dazu, dass Typsysteme zu kompliziert und exotisch werden, wie Konzepte wie „Phantomtypen“ [11] und „Wackeltypen“ [10] bezeugen. Das ist, als würde man versuchen, einen Marathon mit einem Ball und einer Kette zu laufen, die an einem Bein befestigt sind, und triumphierend schreien, dass man es fast geschafft hätte, obwohl man nach der ersten Meile ausstieg. Die statische Typprüfung ist eine Abstraktion des Laufzeitverhaltens Ihres Programms zur Kompilierungszeit und daher notwendigerweise nur teilweise solide und unvollständig. Dies bedeutet, dass Programme aufgrund von Eigenschaften, die nicht von der Typprüfung verfolgt werden, immer noch schief gehen können und dass es Programme gibt, die zwar nicht schief gehen können, aber nicht typgeprüft werden können. Der Impuls, die statische Typisierung weniger partiell und vollständiger zu gestalten, führt dazu, dass Typsysteme zu kompliziert und exotisch werden, wie Konzepte wie „Phantomtypen“ [11] und „Wackeltypen“ [10] bezeugen. Das ist, als würde man versuchen, einen Marathon mit einem Ball und einer Kette zu laufen, die an einem Bein befestigt sind, und triumphierend schreien, dass man es fast geschafft hätte, obwohl man nach der ersten Meile ausstieg. Die statische Typprüfung ist eine Abstraktion des Laufzeitverhaltens Ihres Programms zur Kompilierungszeit und daher notwendigerweise nur teilweise solide und unvollständig. Dies bedeutet, dass Programme aufgrund von Eigenschaften, die nicht von der Typprüfung verfolgt werden, immer noch schief gehen können und dass es Programme gibt, die zwar nicht schief gehen können, aber nicht typgeprüft werden können. Der Impuls, die statische Typisierung weniger partiell und vollständiger zu gestalten, führt dazu, dass Typsysteme zu kompliziert und exotisch werden, wie Konzepte wie „Phantomtypen“ [11] und „Wackeltypen“ [10] bezeugen. Das ist, als würde man versuchen, einen Marathon mit einem Ball und einer Kette zu laufen, die an einem Bein befestigt sind, und triumphierend schreien, dass man es fast geschafft hätte, obwohl man nach der ersten Meile ausstieg. und daher ist es notwendigerweise nur teilweise gesund und unvollständig. Dies bedeutet, dass Programme aufgrund von Eigenschaften, die nicht von der Typprüfung verfolgt werden, immer noch schief gehen können und dass es Programme gibt, die zwar nicht schief gehen können, aber nicht typgeprüft werden können. Der Impuls, die statische Typisierung weniger partiell und vollständiger zu gestalten, führt dazu, dass Typsysteme zu kompliziert und exotisch werden, wie Konzepte wie „Phantomtypen“ [11] und „Wackeltypen“ [10] bezeugen. Das ist, als würde man versuchen, einen Marathon mit einem Ball und einer Kette zu laufen, die an einem Bein befestigt sind, und triumphierend schreien, dass man es fast geschafft hätte, obwohl man nach der ersten Meile ausstieg. und daher ist es notwendigerweise nur teilweise gesund und unvollständig. Dies bedeutet, dass Programme aufgrund von Eigenschaften, die nicht von der Typprüfung verfolgt werden, immer noch schief gehen können und dass es Programme gibt, die zwar nicht schief gehen können, aber nicht typgeprüft werden können. Der Impuls, die statische Typisierung weniger partiell und vollständiger zu gestalten, führt dazu, dass Typsysteme zu kompliziert und exotisch werden, wie Konzepte wie „Phantomtypen“ [11] und „Wackeltypen“ [10] bezeugen. Das ist, als würde man versuchen, einen Marathon mit einem Ball und einer Kette zu laufen, die an einem Bein befestigt sind, und triumphierend schreien, dass man es fast geschafft hätte, obwohl man nach der ersten Meile ausstieg. und dass es Programme gibt, die zwar nicht schief gehen können, aber nicht typgeprüft werden können. Der Impuls, die statische Typisierung weniger partiell und vollständiger zu gestalten, führt dazu, dass Typsysteme zu kompliziert und exotisch werden, wie Konzepte wie „Phantomtypen“ [11] und „Wackeltypen“ [10] bezeugen. Das ist, als würde man versuchen, einen Marathon mit einem Ball und einer Kette zu laufen, die an einem Bein befestigt sind, und triumphierend schreien, dass man es fast geschafft hätte, obwohl man nach der ersten Meile ausstieg. und dass es Programme gibt, die zwar nicht schief gehen können, aber nicht typgeprüft werden können. Der Impuls, die statische Typisierung weniger partiell und vollständiger zu gestalten, führt dazu, dass Typsysteme zu kompliziert und exotisch werden, wie Konzepte wie „Phantomtypen“ [11] und „Wackeltypen“ [10] bezeugen. Das ist, als würde man versuchen, einen Marathon mit einem Ball und einer Kette zu laufen, die an einem Bein befestigt sind, und triumphierend schreien, dass man es fast geschafft hätte, obwohl man nach der ersten Meile ausstieg.

Befürworter dynamisch typisierter Sprachen argumentieren, dass die statische Typisierung zu starr ist und dass sie aufgrund der Weichheit dynamischer Sprachen ideal für Prototyping-Systeme mit sich ändernden oder unbekannten Anforderungen geeignet sind oder mit anderen Systemen interagieren, die sich unvorhersehbar ändern (Daten- und Anwendungsintegration). Natürlich sind dynamisch typisierte Sprachen für den Umgang mit wirklich dynamischem Programmverhalten wie Methodenabfangen, dynamischem Laden, mobilem Code, Laufzeitreflexion usw. unverzichtbar. In der Mutter aller Artikel über Skripte [16] argumentiert John Ousterhout, dass statisch typisierte Systeme Programmiersprachen machen Code weniger wiederverwendbar, ausführlicher, nicht sicherer und weniger ausdrucksstark als dynamisch typisierte Skriptsprachen. Dieses Argument wird buchstäblich von vielen Befürwortern dynamisch typisierter Skriptsprachen nachgeahmt. Wir argumentieren, dass dies ein Irrtum ist und in dieselbe Kategorie fällt wie die Argumentation, dass das Wesen der deklarativen Programmierung darin besteht, die Zuordnung zu eliminieren. Oder wie John Hughes sagt [8], ist es logisch unmöglich, eine Sprache durch Weglassen von Merkmalen leistungsfähiger zu machen. Die Tatsache zu verteidigen, dass es eine gute Sache ist, alle Typprüfungen auf die Laufzeit zu verschieben, ist eine Straußentaktik mit der Tatsache, dass Fehler so früh wie möglich im Entwicklungsprozess erkannt werden sollten. Es ist logisch unmöglich, eine Sprache durch Weglassen von Funktionen leistungsfähiger zu machen. Die Tatsache zu verteidigen, dass es eine gute Sache ist, alle Typprüfungen auf die Laufzeit zu verschieben, ist eine Straußentaktik mit der Tatsache, dass Fehler so früh wie möglich im Entwicklungsprozess erkannt werden sollten. Es ist logisch unmöglich, eine Sprache durch Weglassen von Funktionen leistungsfähiger zu machen. Die Tatsache zu verteidigen, dass es eine gute Sache ist, alle Typprüfungen auf die Laufzeit zu verschieben, ist eine Straußentaktik mit der Tatsache, dass Fehler so früh wie möglich im Entwicklungsprozess erkannt werden sollten.

Vinko Vrsalovic
quelle
37
"Methodenabfangen, dynamisches Laden, mobiler Code, Laufzeitreflexion" kann in Java nur für die Aufzeichnung durchgeführt werden.
Will Hartung
13
Phantomtypen sind nicht "übermäßig kompliziert".
Jon Harrop
12
Der Link zum Meijer-Papier ist ab dem 16.05.2010 unterbrochen.
Jchadhowell
5
@jchadhowell, finden Sie das hier research.microsoft.com/en-us/um/people/emeijer/Papers/…
Srinivas Reddy Thatiparthy
4
@VinkoVrsalovic Statische Sprachen mit Typinferenz und Polymorphismus eignen sich gut für Rapid Prototyping. Sie bieten den gleichen Komfort wie dynamische Sprache und die Sicherheit statischer Sprachen.
Edgar Klerks
119

Statische Systeme versuchen, bestimmte Fehler statisch zu beseitigen, das Programm zu überprüfen, ohne es auszuführen, und zu versuchen, die Solidität in gewisser Hinsicht zu beweisen. Einige Typsysteme können mehr Fehler abfangen als andere. Beispielsweise kann C # bei ordnungsgemäßer Verwendung Nullzeigerausnahmen beseitigen, während Java keine solche Leistung besitzt. Twelf verfügt über ein Typsystem, das tatsächlich garantiert, dass die Beweise beendet werden , wodurch das Problem des Anhaltens "gelöst" wird .

Kein Typsystem ist jedoch perfekt. Um eine bestimmte Fehlerklasse zu beseitigen, müssen sie auch bestimmte einwandfreie Programme ablehnen, die gegen die Regeln verstoßen. Aus diesem Grund löst Twelf das Problem des Anhaltens nicht wirklich, sondern vermeidet es nur, indem es eine große Anzahl perfekt gültiger Beweise herauswirft, die auf seltsame Weise enden. Ebenso lehnt das Java-Typsystem die PersistentVectorImplementierung von Clojure aufgrund der Verwendung heterogener Arrays ab. Es funktioniert zur Laufzeit, aber das Typsystem kann es nicht überprüfen.

Aus diesem Grund bieten die meisten Typsysteme "Escapes", um den statischen Prüfer zu überschreiben. Für die meisten Sprachen haben diese die Form des Castings, obwohl einige (wie C # und Haskell) ganze Modi haben, die als "unsicher" markiert sind.

Subjektiv mag ich statisches Tippen. Richtig implementiert (Hinweis: nicht Java) kann ein statisches Typsystem eine große Hilfe sein, um Fehler zu beseitigen, bevor sie das Produktionssystem zum Absturz bringen. Dynamisch typisierte Sprachen erfordern in der Regel mehr Unit-Tests, was im besten Fall mühsam ist. Statisch typisierte Sprachen können auch bestimmte Funktionen aufweisen, die in dynamischen Typsystemen entweder unmöglich oder unsicher sind ( implizite Konvertierungen fallen mir ein). Es ist alles eine Frage der Anforderungen und des subjektiven Geschmacks. Ich würde die nächste Eclipse in Ruby nicht mehr erstellen, als ich versuchen würde, ein Backup-Skript in Assembly zu schreiben oder einen Kernel mit Java zu patchen.

Oh, und Leute, die sagen, dass " x- Tippen zehnmal produktiver ist als y- Tippen", blasen einfach Rauch. Dynamisches Tippen kann sich in vielen Fällen schneller "anfühlen", verliert jedoch an Boden, sobald Sie tatsächlich versuchen, Ihre ausgefallene Anwendung zum Laufen zu bringen . Ebenso scheint statische Typisierung das perfekte Sicherheitsnetz zu sein, aber ein Blick auf einige der komplizierteren generischen Typdefinitionen in Java lässt die meisten Entwickler nach Augenblinden huschen. Selbst bei Typsystemen und Produktivität gibt es keine Silberkugel.

Schlussbemerkung: Machen Sie sich beim Vergleich von statischer und dynamischer Typisierung keine Sorgen um die Leistung. Moderne JITs wie V8 und TraceMonkey kommen der statischen Sprachleistung gefährlich nahe. Auch die Tatsache, dass Java tatsächlich zu einer inhärent dynamischen Zwischensprache kompiliert wird, sollte ein Hinweis darauf sein, dass dynamisches Tippen in den meisten Fällen nicht der große Leistungskiller ist, den manche Leute ausmachen.

Daniel Spiewak
quelle
5
Über die Leistung. In gewöhnlichen Fällen macht es keinen großen Unterschied, aber in der Hochspannungsmathematik und so gibt es einen echten Unterschied. Tests haben gezeigt, dass ein Funktionsaufruf im Fall von ipy vs C # mit tausend Zyklen unterschiedlich ist. Nur weil Ersteres sicher sein muss, dass es eine Methode gibt.
Dykam
29
Können Sie den Punkt näher erläutern? "C # kann bei ordnungsgemäßer Verwendung Nullzeigerausnahmen beseitigen, während Java keine solche Leistung besitzt." ? Ein Beispiel oder Zitat wäre sehr dankbar.
Srinivas Reddy Thatiparthy
13
"Einige der komplizierteren generischen Typdefinitionen in Java lassen die meisten Entwickler nach Augenblinden huschen" - wenn dies Ihr schlimmstes Beispiel ist, haben Sie offensichtlich kein C ++ verwendet ;-)
bacar
3
"Auch die Tatsache, dass Java tatsächlich zu einer inhärent dynamischen Zwischensprache kompiliert wird, sollte ein Hinweis darauf sein, dass dynamisches Tippen in den meisten Fällen nicht der große Leistungskiller ist, den manche Leute ausmachen." - Wenn Ihr Beispiel für eine Sprache mit "guter Leistung" Java ist, sollten Sie es sich noch einmal überlegen.
Yakk - Adam Nevraumont
" Java kompiliert bis zu einem inhärent dynamischen Zwischenprodukt " - das geht am eigentlichen Punkt vorbei. Die statischen Überprüfungen wurden im Voraus durchgeführt, und daher sind keine zusätzlichen Laufzeitprüfungen erforderlich, die diese vertuschen, da der Compiler Anweisungen auswählt, beispielsweise daddweil er im Voraus weiß, dass die Operanden doubles sind.
Michael Beer
45

Nun, beide sind sehr, sehr, sehr, sehr missverstanden und auch zwei völlig verschiedene Dinge. das schließt sich nicht gegenseitig aus .

Statische Typen sind eine Einschränkung der Grammatik der Sprache. Statisch typisierte Sprachen können streng genommen als nicht kontextfrei bezeichnet werden. Die einfache Wahrheit ist, dass es unpraktisch wird, eine Sprache in kontextfreien Grammatiken vernünftig auszudrücken, die nicht alle ihre Daten einfach als Bitvektoren behandelt. Statische Typsysteme sind Teil der Grammatik der Sprache, wenn überhaupt, sie schränken sie einfach mehr ein als eine kontextfreie Grammatik. Grammatische Überprüfungen finden also tatsächlich in zwei Durchgängen über die Quelle statt. Statische Typen entsprechen dem mathematischen Begriff der Typentheorie, die Typentheorie in der Mathematik schränkt lediglich die Rechtmäßigkeit einiger Ausdrücke ein. Ich kann 3 + [4,7]in der Mathematik nicht sagen , dass dies an der Typentheorie liegt.

Statische Typen sind daher keine Möglichkeit, Fehler aus theoretischer Sicht zu verhindern, sondern eine Einschränkung der Grammatik. Vorausgesetzt, +, 3 und Intervalle haben die üblichen theoretischen Definitionen, wenn wir das Typsystem entfernen, ergibt 3 + [4,7]sich ein ziemlich genau definiertes Ergebnis, das eine Menge ist. 'Laufzeitfehler' existieren theoretisch nicht, die praktische Verwendung des Typsystems besteht darin, Operationen zu verhindern, die für den Menschen keinen Sinn ergeben würden. Operationen sind natürlich immer noch nur das Verschieben und Manipulieren von Bits.

Der Haken dabei ist, dass ein Typsystem nicht entscheiden kann, ob solche Operationen stattfinden werden oder nicht, ob es ausgeführt werden darf. Partitionieren Sie wie in genau die Menge aller möglichen Programme in diejenigen, die einen 'Typfehler' haben werden, und diejenigen, die es nicht sind. Es kann nur zwei Dinge tun:

1: Beweisen Sie, dass Typfehler in einem Programm auftreten werden.
2: Beweisen Sie, dass sie in einem Programm nicht auftreten werden

Das scheint mir zu widersprechen. Ein C- oder Java-Typprüfer lehnt jedoch ein Programm als "ungrammatisch" ab oder nennt es "Typfehler", wenn es bei 2 nicht erfolgreich ist. Es kann nicht beweisen, dass sie nicht auftreten werden. das bedeutet nicht, dass sie nicht auftreten werden, es bedeutet nur, dass es es nicht beweisen kann. Es kann durchaus sein, dass ein Programm ohne Typfehler einfach deshalb abgelehnt wird, weil es vom Compiler nicht bewiesen werden kann. Ein einfaches Beispiel dafürif(1) a = 3; else a = "string";Da dies immer der Fall ist, wird der else-Zweig sicherlich nie im Programm ausgeführt, und es darf kein Typfehler auftreten. Aber es kann diese Fälle nicht allgemein beweisen, deshalb wird es abgelehnt. Dies ist die größte Schwäche vieler statisch typisierter Sprachen. Wenn Sie sich vor sich selbst schützen, sind Sie notwendigerweise auch in Fällen geschützt, in denen Sie sie nicht benötigen.

Entgegen der landläufigen Meinung gibt es jedoch auch statisch typisierte Sprachen, die nach Prinzip 1 funktionieren. Sie lehnen einfach alle Programme ab, von denen sie nachweisen können, dass sie einen Typfehler verursachen, und übergeben alle Programme, von denen sie nicht können. Es ist also möglich, dass sie Programme zulassen, die Typfehler enthalten. Ein gutes Beispiel ist Typed Racket, eine Mischung aus dynamischer und statischer Typisierung. Und einige würden argumentieren, dass Sie das Beste aus beiden Welten in diesem System bekommen.

Ein weiterer Vorteil der statischen Typisierung besteht darin, dass Typen zur Kompilierungszeit bekannt sind und daher vom Compiler verwendet werden können. Wenn wir in Java "string" + "string"oder 3 + 3beide +Token im Text am Ende eine völlig andere Operation und ein völlig anderes Datum darstellen, weiß der Compiler, welche er allein aus den Typen auswählen kann.

Jetzt werde ich hier eine sehr kontroverse Aussage machen, aber mit mir sagen: 'Dynamisches Tippen' gibt es nicht .

Klingt sehr kontrovers, aber es ist wahr, dynamisch typisierte Sprachen sind aus theoretischer Sicht untypisiert . Sie sind nur statisch typisierte Sprachen mit nur einem Typ. Oder einfach ausgedrückt, es handelt sich um Sprachen, die in der Praxis tatsächlich durch eine kontextfreie Grammatik grammatikalisch erzeugt werden.

Warum haben sie keine Typen? Was genau ist ein Laufzeitfehler, da jede Operation für jeden Operanten definiert und zulässig ist? Es ist aus einem theoretischen Beispiel nur eine Nebenwirkung . Wenn das, print("string")was einen String druckt, eine Operation ist, dann length(3)hat das erstere den Nebeneffekt, stringin die Standardausgabe zu schreiben , das letztere einfach error: function 'length' expects array as argument., das war's. Aus theoretischer Sicht gibt es keine dynamisch typisierte Sprache. Sie sind untypisiert

In Ordnung, der offensichtliche Vorteil einer "dynamisch typisierten" Sprache ist die Ausdruckskraft, ein Typensystem ist nichts anderes als eine Einschränkung der Ausdruckskraft. Und im Allgemeinen hätten Sprachen mit einem Typsystem tatsächlich ein definiertes Ergebnis für alle Operationen, die nicht zulässig sind, wenn das Typsystem einfach ignoriert wird. Die Ergebnisse wären für den Menschen einfach nicht sinnvoll. Viele Sprachen verlieren ihre Turing-Vollständigkeit, wenn sie ein Typensystem anwenden.

Der offensichtliche Nachteil ist die Tatsache, dass Operationen auftreten können, die zu Ergebnissen führen würden, die für den Menschen unsinnig sind. Um dem entgegenzuwirken, definieren dynamisch typisierte Sprachen diese Operationen normalerweise neu, anstatt dieses unsinnige Ergebnis zu erzeugen. Sie definieren es neu, um den Nebeneffekt zu haben, dass ein Fehler ausgeschrieben wird und das Programm möglicherweise ganz angehalten wird. Dies ist überhaupt kein "Fehler". Tatsächlich impliziert die Sprachspezifikation dies normalerweise. Dies ist genauso viel Verhalten der Sprache wie das Drucken einer Zeichenfolge aus einer theoretischen Perspektive. Typsysteme zwingen den Programmierer daher, über den Codefluss nachzudenken, um sicherzustellen, dass dies nicht geschieht. Oder in der Tat Grund, damit es tutHappen kann auch in einigen Punkten zum Debuggen nützlich sein und zeigen, dass es sich überhaupt nicht um einen "Fehler" handelt, sondern um eine genau definierte Eigenschaft der Sprache. Tatsächlich schützt der einzige Rest der "dynamischen Typisierung", den die meisten Sprachen haben, vor einer Division durch Null. Dies ist, was dynamische Typisierung ist, es gibt keine Typen, es gibt nicht mehr Typen als diese Null ist ein anderer Typ als alle anderen Zahlen. Was die Leute einen "Typ" nennen, ist nur eine weitere Eigenschaft eines Datums, wie die Länge eines Arrays oder das erste Zeichen einer Zeichenfolge. Und viele dynamisch getippte Sprachen ermöglichen es Ihnen auch, Dinge wie zu schreiben "error: the first character of this string should be a 'z'".

Eine andere Sache ist, dass dynamisch typisierte Sprachen den zur Laufzeit verfügbaren Typ haben und ihn normalerweise überprüfen und damit umgehen und daraus entscheiden können. Theoretisch ist es natürlich nicht anders, als auf das erste Zeichen eines Arrays zuzugreifen und zu sehen, was es ist. Tatsächlich können Sie Ihr eigenes dynamisches C erstellen, nur einen Typ wie long long int verwenden und die ersten 8 Bits verwenden, um Ihren 'Typ' zu speichern und entsprechende Funktionen zu schreiben, die danach suchen und eine Float- oder Integer-Addition durchführen. Sie haben eine statisch typisierte Sprache mit einem Typ oder eine dynamische Sprache.

In der Praxis zeigt dies alles, dass statisch typisierte Sprachen im Allgemeinen beim Schreiben von kommerzieller Software verwendet werden, während dynamisch typisierte Sprachen im Zusammenhang mit der Lösung einiger Probleme und der Automatisierung einiger Aufgaben verwendet werden. Das Schreiben von Code in statisch typisierten Sprachen dauert einfach lange und ist umständlich, da Sie keine Dinge tun können, von denen Sie wissen, dass sie in Ordnung sind, aber das Typensystem schützt Sie trotzdem vor sich selbst vor Fehlern, die Sie nicht machen. Viele Codierer bemerken nicht einmal, dass sie dies tun, weil es sich in ihrem System befindet. Wenn Sie jedoch in statischen Sprachen codieren, umgehen Sie häufig die Tatsache, dass das Typsystem Sie nicht dazu bringt, Dinge zu tun, die nicht schief gehen können, weil es Ich kann nicht beweisen, dass es nicht schief gehen wird.

Wie ich bemerkte, bedeutet "statisch typisiert" im Allgemeinen Fall 2, der schuldig ist, bis seine Unschuld bewiesen ist. Einige Sprachen, die ihr Typensystem überhaupt nicht aus der Typentheorie ableiten, verwenden jedoch Regel 1: Unschuldig bis nachweislich schuldig, was der ideale Hybrid sein könnte. Vielleicht ist Typed Racket etwas für Sie.

Nun, für ein absurderes und extremeres Beispiel implementiere ich derzeit eine Sprache, in der 'Typen' wirklich das erste Zeichen eines Arrays sind, es sind Daten, Daten vom 'Typ', 'Typ', die selbst sind ein Typ und ein Datum, das einzige Datum, das sich selbst als Typ hat. Typen sind nicht endlich oder statisch begrenzt, aber neue Typen können basierend auf Laufzeitinformationen generiert werden.

Zorf
quelle
1
"Viele Sprachen verlieren ihre Turing-Vollständigkeit, wenn sie ein Typensystem anwenden." gilt nicht für übliche Programmiersprachen, oder?
Răzvan Flavius ​​Panda
1
@ RăzvanPanda: Lajla bezog sich wahrscheinlich auf Variationen des typisierten Lambda-Kalküls oder einiger der Programmiersprachen, die sie für Theoremprüfer verwenden. Viele von ihnen können nur Programme ausdrücken, die garantiert angehalten werden und daher nicht vollständig sind. Praktische funktionale Programmiersprachen, die auf diesen Typsystemen basieren, umgehen diese Einschränkung, indem sie den Kernkalkül um rekursive Typen erweitern.
Hugomg
1
"Klingt sehr kontrovers, aber es ist wahr, dynamisch typisierte Sprachen sind aus theoretischer Sicht untypisiert." - ... und sofort weiß ich, dass Sie keine Ahnung haben, wovon Sie sprechen. Dynamische Typisierung bedeutet nur, dass die Typen zu den Werten gehören, nicht zu den Bezeichnern. Es macht es schwieriger, Programme zu beweisen, aber nicht unbedingt unmöglich. Inlining und parametrischer Polymorphismus haben bereits zur Entwicklung einer Optimierung der Verbindungszeit geführt. Dies löst das gleiche Problem wie das Kompilieren optimaler dynamisch typisierter Sprachen: Es kennt alle möglichen Ein- und Ausgänge.
Geschickt gehackt
25

Der vielleicht größte "Vorteil" der dynamischen Typisierung ist die flachere Lernkurve. Es gibt kein zu lernendes Typensystem und keine nicht triviale Syntax für Eckfälle wie Typeinschränkungen. Dies macht das dynamische Schreiben für viel mehr Menschen zugänglich und für viele Menschen möglich, für die hochentwickelte statische Typsysteme unerreichbar sind. Infolgedessen hat sich die dynamische Typisierung im Bildungskontext (z. B. Scheme / Python am MIT) und in domänenspezifischen Sprachen für Nicht-Programmierer (z . B. Mathematica ) durchgesetzt . Dynamische Sprachen haben sich auch in Nischen durchgesetzt, in denen sie wenig oder gar keine Konkurrenz haben (z. B. Javascript).

Die prägnantesten dynamisch typisierten Sprachen (z. B. Perl, APL, J, K, Mathematica ) sind domänenspezifisch und können in den Nischen, für die sie entwickelt wurden , wesentlich prägnanter sein als die prägnantesten statisch typisierten Allzwecksprachen (z. B. OCaml ) .

Die Hauptnachteile der dynamischen Typisierung sind:

  • Laufzeitfehler.

  • Es kann sehr schwierig oder sogar praktisch unmöglich sein, das gleiche Maß an Korrektheit zu erreichen, und erfordert erheblich mehr Tests.

  • Keine vom Compiler verifizierte Dokumentation.

  • Schlechte Leistung (normalerweise zur Laufzeit, manchmal aber auch zur Kompilierungszeit, z. B. Stalin-Schema) und unvorhersehbare Leistung aufgrund der Abhängigkeit von ausgeklügelten Optimierungen.

Persönlich bin ich mit dynamischen Sprachen aufgewachsen, würde sie aber als Profi nicht mit einer 40-Fuß-Stange berühren, es sei denn, es gäbe keine anderen realisierbaren Optionen.

Jon Harrop
quelle
2
Ich würde sagen, niedrigere Eintrittsbarriere, aber Meisterschaft ist nicht weniger eine Lernkurve.
Erik Reppen
Ist die Lernkurve nicht geringer, weil Sie kein Typensystem zum Lernen haben?
Jon Harrop
Es gibt immer noch ein Typensystem. Sie können vernünftige Vermutungen anstellen, was passiert, wenn Sie einen Bool und eine Zeichenfolge hinzufügen. Oft hilft es jedoch sehr, einige tatsächliche Details darüber zu kennen, wie Typen in einer dynamisch typisierten Sprache erzwungen werden. Das ist es, was viele der strengen Leute nicht bekommen. Wir lernen dieses Zeug tatsächlich.
Erik Reppen
@ErikReppen: Wir verwenden unterschiedliche Definitionen von "Typsystem". Ich bezog mich darauf, kein statisches Typsystem lernen zu müssen, z. B. algebraische Datentypen, Generika. Die "Typen", auf die Sie sich beziehen, sind nur Daten. Die Tatsache, dass einige Funktionen einige Daten zur Laufzeit ablehnen, ist universell.
Jon Harrop
12

Aus Artimas Typisierung: Stark gegen schwach, statisch gegen dynamisch Artikel:

Starke Typisierung verhindert Mischvorgänge zwischen nicht übereinstimmenden Typen. Um Typen zu mischen, müssen Sie eine explizite Konvertierung verwenden

Schwache Typisierung bedeutet, dass Sie Typen ohne explizite Konvertierung mischen können

In der Arbeit von Pascal Costanza, Dynamische vs. statische Typisierung - Eine musterbasierte Analyse (PDF), behauptet er, dass statische Typisierung in einigen Fällen fehleranfälliger ist als dynamische Typisierung. Einige statisch typisierte Sprachen zwingen Sie, die dynamische Typisierung manuell zu emulieren, um "The Right Thing" auszuführen. Es wird bei Lambda the Ultimate diskutiert .

Mark Cidade
quelle
1
"Statische Eingabe ist fehleranfälliger als dynamische Eingabe" - Ja, ja und DOPPELT ja! Ich habe viel Erfahrung in beiden Arten von Sprachen, und in jedem Fall "funktioniert" die dynamische Sprache "nur", während die statische Sprache die doppelte Debugging-Zeit benötigt (siehe C ++ und Delphi). Dies ist häufig auf Typprobleme zurückzuführen, insbesondere auf die Datenübertragung zwischen Modulen und Funktionen mit verrückten Typen. Obwohl es alle möglichen theoretischen Fehler gibt, die dynamische Sprachen angeblich verursachen können, ist es in der Praxis SEHR selten, dass ich auf einen Fehler stoße, der durch Typenzwang verursacht wird, es sei denn, Sie sind ein schlechter Programmierer, der dynamische Typen missbraucht.
Dallas
7
Ich habe vor einigen Jahren einen Entwurf für ein Costanza-Papier gelesen. Überall, wo er "statisch" geschrieben hatte, meinte er wirklich speziell "Java". Ich gab ihm Dutzende von Gegenbeispielen in Sprachen wie OCaml, die seine Behauptungen widerlegten, aber er ging voran und veröffentlichte sie trotzdem. Wie es aussieht, veröffentlicht er immer noch denselben alten Unsinn. In diesem Artikel behauptet er beispielsweise, "C # sei im Allgemeinen eine schlechte Kopie von Java". Das hat keinen Platz in einer wissenschaftlichen Arbeit ...
Jon Harrop
@dallin Meine Erfahrung ist das genaue Gegenteil: Da ich viel in C, C ++, Java, Python, Perl und dergleichen programmieren muss, würde ich niemals etwas Größeres als ein kleines Optimierungsprogramm in einer dynamisch typisierten Sprache starten, wenn ich nicht dazu gezwungen würde. In Python zittere ich immer noch, wenn ich an ein WSGI-Projekt denke: Die Rückrufe, die ich überschreiben musste, wurden in Referenzen von Objekten übergeben, und der Code schien gut zu funktionieren, als er abstürzte, weil sich herausstellte, dass es manchmal keine Objekte, sondern einige Elementtypen sind bestanden werden. Eine Sprache, die es so einfach macht, solche Buggy-Sachen zu erstellen, ist geradezu gefährlich.
Michael Beer
@MichaelBeer Man könnte auch sagen, dass eine Sprache wie C / C ++, mit der Sie den Speicher direkt verwalten können, geradezu gefährlich ist! Ich habe sicherlich stundenlang mit Speicherfehlern gerungen. Riesige Java-Projekte sind auch kein Picknick. In jeder Sprache müssen Sie die Gefahren der Sprache und der bewährten Praktiken verstehen. Die absolut schlechtesten Projekte, an denen ich je gearbeitet habe, waren Team-PHP-Projekte mit wenig Struktur, aber ich habe auch an Projekten mit dynamischen Sprachen gearbeitet, die ein Traum waren, wenn sie ein gutes Framework und gute Programmierpraktiken verwendeten.
Dallas
@dallin Einverstanden, jede Sprache hat ihre Fallstricke. Aber die Fehler, auf die ich mich bezog, sind jeder dynamisch typisierten Sprache inhärent. Die Möglichkeit, den Speicher direkt zu manipulieren, ist keine inhärente Eigenschaft statisch typisierter Sprachen. Sie können sich dynamisch typisierte Sprachen vorstellen, mit denen Sie mem direkt bearbeiten können. Ich stimme zu, dass C ++ eine reine Katastrophe ist, wobei der Erfinder der Sprache selbst glaubt, dass keine einzige Person auf diesem Planeten in der Lage ist, alle Teile der Sprache zu kennen. Dies kann jedoch nicht darauf zurückgeführt werden, dass C ++ statisch typisiert ist, sondern ein Monster, das seit 30 Jahren wächst ...
Michael Beer
3

Es kommt auf den Kontext an. Es gibt viele Vorteile, die sowohl für dynamisch typisierte Systeme als auch für stark typisierte Systeme geeignet sind. Ich bin der Meinung, dass der Fluss der Sprache dynamischer Typen schneller ist. Die dynamischen Sprachen sind nicht an Klassenattribute gebunden, und der Compiler denkt darüber nach, was im Code vor sich geht. Du hast ein bisschen Freiheit. Darüber hinaus ist die dynamische Sprache normalerweise ausdrucksvoller und führt zu weniger Code, was gut ist. Trotzdem ist es fehleranfälliger, was ebenfalls fraglich ist und mehr von der Abdeckung durch Unit-Tests abhängt. Es ist ein einfacher Prototyp mit dynamischer Sprache, aber die Wartung kann zum Albtraum werden.

Der Hauptvorteil gegenüber statisch typisierten Systemen ist die IDE-Unterstützung und sicherlich der statische Analysator von Code. Nach jeder Codeänderung werden Sie sicherer in Bezug auf Code. Die Wartung ist mit solchen Werkzeugen ein Kinderspiel.

AndrewG
quelle
0

Es gibt viele verschiedene Dinge über statische und dynamische Sprachen. Für mich besteht der Hauptunterschied darin, dass die Variablen in dynamischen Sprachen keine festen Typen haben. Stattdessen sind die Typen an Werte gebunden. Aus diesem Grund ist der genaue Code, der ausgeführt wird, bis zur Laufzeit unbestimmt.

In frühen oder naiven Implementierungen ist dies ein enormer Leistungsverlust, aber moderne JITs kommen dem Besten, das Sie mit der Optimierung statischer Compiler erzielen können, auf verlockende Weise nahe. (In einigen Randfällen sogar noch besser).

Javier
quelle
0

Es geht um das richtige Werkzeug für den Job. Weder ist 100% der Zeit besser. Beide Systeme wurden vom Menschen geschaffen und weisen Mängel auf. Sorry, aber wir saugen und machen perfekte Sachen.

Ich mag dynamisches Tippen, weil es mir aus dem Weg geht, aber ja, Laufzeitfehler können auftreten, die ich nicht geplant habe. Wobei als statische Eingabe die oben genannten Fehler behoben werden können, aber ein Anfänger (in getippten Sprachen) den Programmierer verrückt macht, der versucht, zwischen einem konstanten Zeichen und einer Zeichenfolge zu wechseln.

JJ
quelle
-3

Statische Typisierung: Die Sprachen wie Java und Scala sind statisch typisiert.

Die Variablen müssen definiert und initialisiert werden, bevor sie in einem Code verwendet werden.

zum Beispiel. int x; x = 10;

System.out.println (x);

Dynamische Typisierung: Perl ist eine dynamisch typisierte Sprache.

Variablen müssen nicht initialisiert werden, bevor sie im Code verwendet werden.

y = 10; Verwenden Sie diese Variable im späteren Teil des Codes

Prakhyat
quelle
5
Dies hat nichts mit dem Typsystem zu tun.
Thiago Negri