it-swarm.com.de

Dynamische Schriftsprachen versus statische Schriftsprachen

Welche Vor- und Nachteile haben dynamische Schriftsprachen im Vergleich zu statischen Schriftsprachen?

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

202
cvs

Die Fähigkeit des Interpreters, Typ- und Typkonvertierungen abzuleiten, beschleunigt die Entwicklungszeit, kann aber auch zu Laufzeitfehlern führen, die in einer statisch typisierten Sprache, in der Sie sie zur Kompilierungszeit abfangen, einfach nicht zu bekommen sind. Aber was besser ist (oder auch wenn das immer wahr ist), wird heutzutage (und seit langer Zeit) in der Community heiß diskutiert.

Eine gute Interpretation des Problems ist statische Eingabe, wenn möglich, dynamische Eingabe 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 eine frühere Erkennung von Programmierfehlern (z. B. Verhinderung des Hinzufügens einer Ganzzahl zu einem Booleschen Wert), eine bessere Dokumentation in Form von Typensignaturen (z. B. Einbeziehung von Anzahl und Art der Argumente beim Auflösen von Namen) usw. umfassen Möglichkeiten zur Compileroptimierung (z. B. Ersetzen von virtuellen Aufrufen durch direkte Aufrufe, wenn der genaue Empfängertyp statisch bekannt ist), erhöhte Laufzeiteffizienz (z. B. müssen nicht alle Werte einen dynamischen Typ tragen) und eine bessere Entwicklungszeit für Entwickler (z. B. Wissen) Der Empfängertyp IDE kann ein Dropdown-Menü aller zutreffenden Mitglieder anzeigen.) Statische Tippfanatiker versuchen uns glauben zu machen, dass „gut getippte Programme nichts falsch machen können“ das klingt sicherlich beeindruckend, es ist eine ziemlich leere Aussage. Die statische Typprüfung ist eine Abstraktion des Laufzeitverhaltens Ihres Programms zur Kompilierungszeit, und daher ist es notwendigerweise nur teilweise sound und i unvollständig. Dies bedeutet, dass Programme aufgrund von Eigenschaften, die von der Typprüfung nicht verfolgt werden, immer noch fehlerhaft sein können und dass es Programme gibt, die zwar nicht fehlerfrei sind, jedoch nicht einer Typprüfung unterzogen werden können. Der Impuls, das statische Tippen weniger partiell und vollständiger zu machen, führt dazu, dass Typensysteme übermäßig kompliziert und exotisch werden, wie Konzepte wie „Phantomtypen“ [11] und „Wackeltypen“ [10] belegen. Dies ist wie der Versuch, einen Marathon mit einem Ball und einer Kette zu laufen, die an Ihrem Bein befestigt sind, und triumphierend zu schreien, dass Sie es fast geschafft haben, obwohl Sie nach der ersten Meile aussteigen mussten.

Verfechter von dynamisch getippten Sprachen argumentieren, dass die statische Typisierung zu starr ist und dass die Weichheit von dynamisch getippten Sprachen sie ideal für Prototyping-Systeme mit sich ändernden oder unbekannten Anforderungen geeignet macht oder die mit anderen Systemen interagieren, die sich unvorhersehbar ändern (Daten- und Anwendungsintegration). Dynamisch getippte Sprachen sind natürlich unverzichtbar, um mit wirklich dynamischem Programmverhalten wie Abfangen von Methoden, dynamischem Laden, mobilem Code, Laufzeitreflexion usw. umzugehen. John Ousterhout, Mutter aller Artikel zu Skripten [16], argumentiert, dass Systeme statisch getippt sind Programmiersprachen machen Code weniger wiederverwendbar, ausführlicher, nicht sicherer und weniger aussagekräftig als dynamisch getippte Skriptsprachen. Dieses Argument wird von vielen Befürwortern dynamisch geschriebener Skriptsprachen wörtlich ausgesprochen. Wir argumentieren, dass dies ein Irrtum ist und in dieselbe Kategorie fällt wie die Argumentation, dass das Wesentliche der deklarativen Programmierung darin besteht, Zuweisungen zu eliminieren. Oder wie John Hughes [8] sagt, ist es eine logische Unmöglichkeit, eine Sprache leistungsfähiger zu machen, indem Merkmale weggelassen werden. Die Tatsache zu verteidigen, dass es gut ist, die gesamte Typprüfung auf die Laufzeit hinauszuschieben, spielt eine Straußen-Taktik mit der Tatsache, dass Fehler so früh wie möglich im Entwicklungsprozess abgefangen werden sollten.

138
Vinko Vrsalovic

Statische Systeme versuchen, bestimmte Fehler statisch zu beseitigen, das Programm zu inspizieren, ohne es auszuführen, und versuchen, die Richtigkeit in bestimmter Hinsicht zu beweisen. Einige Typsysteme können mehr Fehler abfangen als andere. Zum Beispiel kann C # bei richtiger Verwendung Nullzeiger-Ausnahmen eliminieren, wohingegen Java hat keine solche Potenz. Twelf hat ein Typsystem, das tatsächlich garantiert, dass Beweise enden , " Lösen "des Halteproblems .

Kein Typensystem ist jedoch perfekt. Um eine bestimmte Fehlerklasse auszuschließen, müssen sie auch bestimmte einwandfrei gültige Programme ablehnen, die gegen die Regeln verstoßen. Dies ist der Grund, warum Twelf das Problem des Anhaltens nicht wirklich löst, sondern es nur vermeidet, indem es eine große Anzahl perfekt gültiger Beweise auswirft, die auf seltsame Weise enden. Ebenso lehnt Javas Typsystem die Implementierung von Clojure PersistentVector ab, da heterogene Arrays verwendet werden. Es funktioniert zur Laufzeit, aber das Typsystem kann es nicht verifizieren.

Aus diesem Grund bieten die meisten Typsysteme "Escapes", Möglichkeiten zum Überschreiben des statischen Prüfers. Bei den meisten Sprachen handelt es sich um Castings, obwohl einige (wie C # und Haskell) ganze Modi haben, die als "unsicher" gekennzeichnet sind.

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

Oh, und Leute, die sagen, dass " x tippen 10-mal produktiver ist als y Tippen "bläst einfach Rauch. Dynamisches Tippen "fühlt" sich in vielen Fällen schneller an, verliert jedoch an Boden, sobald Sie tatsächlich versuchen, Ihre ausgefallene Anwendung zum Ausführen zu bringen . Ebenso mag statisches Tippen wie ein perfektes Sicherheitsnetz erscheinen, aber ein Blick auf einige der komplizierteren generischen Typdefinitionen in Java) lässt die meisten Entwickler nach Blinden huschen. Auch bei Schriftsystemen und Produktivität gibt es keine silberne Kugel.

Letzter Hinweis: Machen Sie sich beim Vergleich der statischen mit der dynamischen Eingabe keine Gedanken über die Leistung. Moderne JITs wie V8 und TraceMonkey kommen der statischen Sprachleistung gefährlich nahe. Auch die Tatsache, dass Java tatsächlich in eine inhärent dynamische Zwischensprache kompiliert wird, sollte ein Hinweis darauf sein, dass dynamisches Tippen in den meisten Fällen nicht der große Leistungsmörder ist, mit dem manche Leute es zu tun haben Sein.

119
Daniel Spiewak

Nun, beide sind sehr, sehr, sehr missverstanden und auch zwei völlig verschiedene Dinge. die sich nicht gegenseitig ausschließen.

Statische Typen sind eine Einschränkung der Grammatik der Sprache. Statisch typisierte Sprachen können streng genommen nicht als kontextfrei bezeichnet werden. Die einfache Wahrheit ist, dass es unpraktisch wird, eine Sprache in kontextfreien Grammatiken auszudrücken, die nicht alle ihre Daten einfach als Bitvektoren behandeln. Statische Typsysteme sind Teil der Grammatik der Sprache, wenn überhaupt, sie schränken sie einfach mehr ein als eine kontextfreie Grammatik es könnte, grammatische Überprüfungen erfolgen also tatsächlich in zwei Durchgängen über die Quelle. Statische Typen entsprechen dem mathematischen Begriff der Typentheorie, die Typentheorie in der Mathematik schränkt lediglich die Legalität einiger Ausdrücke ein. In Mathematik kann ich nicht 3 + [4,7] Sagen, das liegt an der Typentheorie.

Statische Typen sind daher aus theoretischer Sicht keine Möglichkeit, Fehler zu vermeiden, sondern eine Einschränkung der Grammatik. In der Tat, vorausgesetzt, dass +, 3 und Intervalle die üblichen satztheoretischen Definitionen haben, wenn wir das Typensystem entfernen 3 + [4,7] Hat ein ziemlich genau definiertes Ergebnis, das eine Menge ist. 'Laufzeitfehler' existieren theoretisch nicht, der praktische Nutzen 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 daran ist, dass ein Typsystem nicht entscheiden kann, ob solche Operationen stattfinden oder nicht, ob es ausgeführt werden darf. Wie in partitionieren Sie genau die Menge aller möglichen Programme in solche, die einen "Typfehler" aufweisen, und solche, die es nicht sind. Es kann nur zwei Dinge tun:

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

Das könnte so aussehen, als würde ich mich selbst widersprechen. Aber ein C oder Java type checker) lehnt ein Programm als 'ungrammatisch' oder als 'type error' ab, wenn es kann. t ist bei 2 erfolgreich. Es kann nicht beweisen, dass sie nicht auftreten werden. Das bedeutet nicht, dass sie nicht auftreten werden, sondern nur, dass sie es nicht beweisen können Es kann durchaus sein, dass ein Programm, das keinen Tippfehler aufweist, einfach deshalb abgelehnt wird, weil es vom Compiler nicht bewiesen werden kann. Ein einfaches Beispiel ist if(1) a = 3; else a = "string";, sicherlich, weil es immer wahr ist, das andere -branch wird niemals im Programm ausgeführt, und es darf kein Tippfehler auftreten. Es kann diese Fälle jedoch nicht generell beweisen, weshalb es abgelehnt wird. Dies ist die Hauptschwäche vieler statisch typisierter Sprachen, wenn es darum geht, Sie zu schützen Gegen dich selbst bist du notwendigerweise auch in Fällen geschützt, in denen du es nicht brauchst.

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. So ist es möglich, dass sie Programme zulassen, die Tippfehler enthalten. Ein gutes Beispiel hierfür ist Typed Racket. Es ist eine Mischung aus dynamischer und statischer Eingabe. 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 der Compiler diese verwenden kann. Wenn wir in Java do "string" + "string" Oder 3 + 3 Beide + Token im Text am Ende eine völlig andere Operation und ein völlig anderes Datum darstellen, das Der Compiler weiß, welche Typen er allein auswählen muss.

Jetzt werde ich hier eine sehr kontroverse Aussage machen, aber bedenke: 'dynamic typing' existiert nicht.

Klingt sehr kontrovers, aber es stimmt, dynamisch getippte Sprachen sind aus theoretischer Sicht untypisiert . Es handelt sich lediglich um statisch typisierte Sprachen mit nur einem Typ. 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 ist ein Laufzeitfehler genau, da jede Operation für jeden Operanten definiert und zulässig ist? Es ist von einem theoretischen Beispiel nur eine Nebenwirkung . Wenn das Ausführen von print("string"), das eine Zeichenfolge druckt, eine Operation ist, dann ist dies auch length(3), die erstere hat den Nebeneffekt, dass string in die Standardausgabe geschrieben wird, die 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 getippten" Sprache ist die Ausdruckskraft, ein Typensystem ist nichts anderes als eine Einschränkung der Ausdruckskraft. Und im Allgemeinen hätten Sprachen mit einem Typensystem tatsächlich ein definiertes Ergebnis für alle Operationen, die nicht zulässig sind, wenn das Typensystem einfach ignoriert wird. Die Ergebnisse wären für den Menschen einfach nicht sinnvoll. Viele Sprachen verlieren nach Anwendung eines Typensystems ihre Turing-Vollständigkeit.

Der offensichtliche Nachteil ist die Tatsache, dass Operationen auftreten können, die zu für Menschen unsinnigen Ergebnissen führen würden. Um dem entgegenzuwirken, definieren dynamisch typisierte Sprachen diese Operationen in der Regel neu, anstatt das unsinnige Ergebnis zu erzeugen, und definieren es so, dass der Nebeneffekt besteht, dass ein Fehler ausgegeben und möglicherweise das Programm insgesamt angehalten wird. Dies ist überhaupt kein "Fehler". Tatsächlich impliziert die Sprachspezifikation dies normalerweise. Dies ist so viel Verhalten der Sprache wie das Drucken eines Strings aus einer theoretischen Perspektive. Typsysteme zwingen den Programmierer daher, über den Fluss des Codes nachzudenken, um sicherzustellen, dass dies nicht geschieht. In der Tat kann der Grund dafür, dass es passiert , auch in einigen Punkten für das Debuggen nützlich sein, um zu zeigen, dass es sich nicht um einen "Fehler" handelt, sondern um einen Brunnen 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 dynamisches Tippen ist, es gibt keine Typen, es gibt nicht mehr Typen als diese Null ist ein anderer Typ als alle anderen Zahlen. Was Leute einen "Typ" nennen, ist nur eine andere Eigenschaft eines Datums, wie die Länge eines Arrays oder das erste Zeichen einer Zeichenfolge. In vielen dynamisch getippten Sprachen können Sie auch Dinge wie "error: the first character of this string should be a 'z'" Ausschreiben.

Eine andere Sache ist, dass dynamisch getippte Sprachen den Typ zur Laufzeit zur Verfügung 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 Funktionen entsprechend zu schreiben, die nach ihm suchen und eine Gleitkomma- oder Ganzzahladdition durchführen. Sie haben eine statisch typisierte Sprache mit einem Typ oder eine dynamische Sprache.

In der Praxis werden statisch typisierte Sprachen im Allgemeinen beim Schreiben von kommerzieller Software verwendet, wohingegen dynamisch typisierte Sprachen im Zusammenhang mit der Lösung einiger Probleme und der Automatisierung einiger Aufgaben verwendet werden. Das Schreiben von Code in statisch getippten Sprachen dauert einfach lange und ist umständlich, da Sie keine Dinge tun können, von denen Sie wissen, dass sie sich als in Ordnung erweisen werden, aber das Typensystem schützt Sie trotzdem vor sich selbst vor Fehlern, die Sie nicht machen. Viele Programmierer merken nicht einmal, dass sie dies tun, weil es in ihrem System ist. 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 kann nicht beweisen, dass es nicht schief gehen wird.

Wie ich bereits bemerkt habe, bedeutet "statisch getippt" im Allgemeinen Fall 2, der schuldig ist, bis er seine Unschuld bewiesen hat. Aber einige Sprachen, die ihr Typensystem überhaupt nicht aus der Typentheorie ableiten, wenden Regel 1 an: Unschuldig bis zum Beweis der Schuld, die die ideale Hybride sein könnte. Vielleicht ist Typed Racket 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', der selbst ist 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.

45
Zorf

Möglicherweise ist der größte "Vorteil" des dynamischen Tippens die flachere Lernkurve. Es gibt kein zu lernendes Typensystem und keine nicht triviale Syntax für Eckfälle wie Typbeschränkungen. Dies macht dynamisches Schreiben für viel mehr Menschen zugänglich und für viele Menschen, für die ausgeklügelte statische Schriftsysteme unerreichbar sind, durchführbar. Infolgedessen hat sich die dynamische Typisierung im Bildungsbereich (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äzisesten dynamisch typisierten Sprachen (z. B. Perl, APL, J, K, Mathematica ) sind domänenspezifisch und können wesentlich präziser sein als die präzisesten statisch typisierten Mehrzwecksprachen (z. B. - OCaml ) in den Nischen, für die sie entworfen wurden.

Die Hauptnachteile der dynamischen Typisierung sind:

  • Laufzeitfehler.

  • Es kann sehr schwierig oder sogar praktisch unmöglich sein, dasselbe Korrektheitsniveau zu erreichen, und es sind erheblich mehr Tests erforderlich.

  • Keine vom Compiler überprüfte Dokumentation.

  • Schlechte Leistung (normalerweise zur Laufzeit, aber manchmal stattdessen 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, aber ich würde sie als Profi nicht mit einer 40-Fuß-Stange anfassen, es sei denn, es gäbe keine anderen realisierbaren Optionen.

25
Jon Harrop

Aus Artimas Typisierung: Stark vs. Schwach, Statisch vs. 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 in In einigen Fällen ist die statische Typisierung fehleranfälliger als die dynamische Typisierung. Bei einigen statisch getippten Sprachen müssen Sie die dynamische Eingabe manuell emulieren, um "The Right Thing" ausführen zu können. Es wird diskutiert bei Lambda the Ultimate .

12
Mark Cidade

Das hängt vom Kontext ab. Es gibt viele Vorteile, die sowohl für dynamische 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 in der Regel ausdrucksvoller und führt zu weniger Code, der gut ist. Trotzdem ist es fehleranfälliger, was ebenfalls fragwürdig ist und mehr von der Abdeckung durch Einheitentests abhängt. Es ist ein einfacher Prototyp mit dynamischer Sprache, aber die Wartung kann zum Albtraum werden.

Der Hauptgewinn gegenüber statisch typisierten Systemen ist die IDE= Unterstützung und sicher statische Analyse von Code. Sie werden nach jeder Codeänderung sicherer im Code. Die Wartung ist mit solchen Tools ein Kinderspiel.

3
AndrewG

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

Ich mag dynamisches Tippen, weil es mir aus dem Weg geht, aber es können sich Laufzeitfehler einschleichen, die ich nicht eingeplant habe. Wobei als statische Typisierung die oben genannten Fehler behoben werden können, aber ein Anfänger (in getippten Sprachen) den Versuch verrückt macht, zwischen einem konstanten Zeichen und einem String zu gießen.

0
J.J.

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 eine enorme Belastung für die Leistung, aber moderne JITs erreichen nahezu das Beste, was Sie mit der Optimierung statischer Compiler erreichen können. (In einigen Fällen sogar noch besser).

0
Javier