Sprachen des dynamischen Typs im Vergleich zu Sprachen des statischen Typs

Was sind die Vorteile und Einschränkungen von dynamischen Sprachen im Vergleich zu statischen Sprachen?

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

Solutions Collecting From Web of "Sprachen des dynamischen Typs im Vergleich zu Sprachen des statischen Typs"

Die Fähigkeit des Interpreters, Typ- und Typkonvertierungen abzuleiten, beschleunigt die Entwicklungszeit, kann aber auch Laufzeiterrors verursachen, die Sie in einer statisch typisierten Sprache, in der Sie sie zum Zeitpunkt der Kompilierung abfangen, nicht erhalten. Aber wer besser ist (oder auch wenn das immer stimmt), wird heutzutage (und seit langer Zeit) in der Community heiß diskutiert.

Eine gute Meinung zu diesem Thema stammt von ” Static Typing Where allowable, Dynamic Typing Wenn erforderlich: 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 Programmiererrorsn (zB das Verhindern des Hinzufügens einer Ganzzahl zu einem booleschen Wert), bessere Dokumentation in Form von Typensignaturen (zB Einbeziehen von Zahl und Arten von Argumenten beim Auflösen von Namen) sind 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 Laufzeit – Effizienz (z. B. müssen nicht alle Werte einen dynamischen Typ tragen) und eine bessere Entwicklungszeit des Entwicklers (z der Typ des Empfängers, kann die IDE ein Dropdown-Menü aller anwendbaren Mitglieder darstellen). Static Typing Fanatiker versuchen uns glauben zu machen, dass “gut typisierte Programme nicht schief laufen können”. Das klingt zwar eindrucksvoll, aber es ist eine ziemlich leere Aussage. Statische Typprüfung ist eine Kompilierungszeit-Abstraktion des Laufzeitverhaltens Ihres Programms und daher ist es notwendigerweise nur teilweise gesund und unvollständig. Dies bedeutet, dass Programme aufgrund von Eigenschaften, die vom Typüberprüfer nicht verfolgt werden, immer noch schief gehen können und dass es Programme gibt, die zwar nicht schief gehen können, aber nicht typisiert werden können. Der Impuls, statische Typisierung weniger partiell und vollständiger zu machen, führt dazu, dass Typsysteme übermäßig kompliziert und exotisch werden, wie Konzepte wie “Phantomtypen” [11] und “Wobbeltypen” [10] zeigen. Das ist wie der Versuch, einen Marathon mit einer an dein Bein gefesselten Kugel und Kette zu laufen und triumphierend zu schreien, dass du es fast geschafft hättest, obwohl du nach der ersten Meile gerettet hast.

Befürworter von dynamisch typisierten Sprachen argumentieren, dass statische Typisierung zu starr ist und dass die Flexibilität dynamischer Sprachen sie ideal für Prototyping-Systeme mit sich ändernden oder unbekannten Anforderungen macht oder mit anderen Systemen interagieren, die sich unvorhersehbar verändern (Daten- und Anwendungsintegration). Natürlich sind dynamisch typisierte Sprachen für den Umgang mit wirklich dynamischem Programmverhalten wie Methodenabfangen, dynamisches Laden, mobiler Code, Laufzeitreflexion usw. unverzichtbar. In der Mutter aller Artikel über Skripting [16] argumentiert John Ousterhout mit den statisch typisierten Systemen 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 parodiert. Wir argumentieren, dass dies ein Trugschluss ist und fällt in die gleiche Kategorie wie die Argumentation, dass das Wesen der deklarativen Programmierung die Eliminierung von Aufgaben ist. Oder wie John Hughes sagt [8], ist es eine logische Unmöglichkeit, eine Sprache durch das Weglassen von Merkmalen leistungsfähiger zu machen. Die Tatsache zu verteidigen, dass eine Verzögerung der Typprüfung zur Laufzeit eine gute Sache ist, spielt Strauß-Taktiken mit der Tatsache, dass Fehler so früh wie möglich im Entwicklungsprozess aufgefangen werden sollten.

Systeme vom statischen Typ versuchen, bestimmte Fehler statisch zu beseitigen, das Programm zu untersuchen, ohne es auszuführen, und zu versuchen, in gewisser Hinsicht die Zuverlässigkeit zu beweisen. Einige Typsysteme können mehr Fehler als andere erfassen. Zum Beispiel kann C # Nullzeiger-Ausnahmen eliminieren, wenn sie richtig verwendet werden, während Java keine solche Macht besitzt. Twelf hat ein Typsystem, das tatsächlich garantiert, dass die Beweise beendet werden , wodurch das Halteproblem “getriggers” wird.

Allerdings ist kein Typsystem perfekt. Um eine bestimmte class von Fehlern zu eliminieren, müssen sie auch einige perfekt gültige Programme ablehnen, die gegen die Regeln verstoßen. Dies ist der Grund, warum Twelf das Halteproblem nicht wirklich triggers, es vermeidet es einfach, indem es eine große Anzahl von vollkommen gültigen Beweisen auswirft, die auf seltsame Weise enden. Entsprechend lehnt Javas Typsystem Clojures PersistentVector Implementierung aufgrund der Verwendung von heterogenen Arrays ab. Es funktioniert zur Laufzeit, aber das Typsystem kann es nicht verifizieren.

Aus diesem Grund bieten die meisten Typsysteme “Escapes”, Möglichkeiten, den statischen Checker zu überschreiben. Für die meisten Sprachen haben diese die Form von Casting, obwohl einige (wie C # und Haskell) ganze Modi haben, die als “unsicher” markiert sind.

Subjektiv mag ich statische Typisierung. Richtig implementiert (Hinweis: nicht Java), kann ein System vom statischen Typ eine große Hilfe beim Aussortieren von Fehlern sein, bevor es das Produktionssystem zum Absturz bringt. Dynamisch typisierte Sprachen erfordern in der Regel mehr Komponententests, was zu den besten Zeiten mühsam ist. Außerdem können statisch typisierte Sprachen bestimmte Merkmale aufweisen, die in dynamischen Systemtypen 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 nicht mehr das nächste Eclipse in Ruby erstellen, als ich versuchen würde, ein Backup-Skript in Assembly zu schreiben oder einen coreel mit Java zu patchen.

Oh, und Leute, die sagen, dass ” x Tippen zehnmal produktiver ist als Tippen”, sind einfach Rauch. Dynamisches Tippen kann sich in vielen Fällen schneller “anfühlen”, verliert jedoch an Boden, wenn Sie tatsächlich versuchen, Ihre ausgefallene Anwendung zum Laufen zu bringen . Ebenso mag die statische Typisierung als das perfekte Sicherheitsnetz erscheinen, aber ein Blick auf einige der komplizierteren generischen Typdefinitionen in Java schickt die meisten Entwickler nach Augenscheuklappen. Selbst mit Typsystemen und Produktivität gibt es keine Wunderwaffe.

Schlussbemerkung: Sorgen Sie sich nicht um die performance, wenn Sie statische mit dynamischer Typisierung vergleichen. Moderne JITs wie V8 und TraceMonkey kommen gefährlich nahe an die statische Sprachleistung heran. Auch die Tatsache, dass Java tatsächlich zu einer inhärent dynamischen Zwischensprache kompiliert, sollte ein Hinweis darauf sein, dass dynamisches Tippen in den meisten Fällen nicht der große performances-Killer ist, von dem einige Leute ausgehen.

Nun, beide sind sehr, 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 getippte Sprachen könnten streng genommen nicht kontextfrei sein. Die einfache Wahrheit ist, dass es unbequem wird, eine Sprache in kontextfreien Grammatiken auszudrücken, die nicht alle ihre Daten einfach als Bitvektoren behandelt. Statische Systeme sind Teil der Grammatik der Sprache, wenn überhaupt, sie beschränken sie lediglich mehr als eine kontextfreie Grammatik, grammatische Überprüfungen können also in zwei Durchläufen über die Quelle stattfinden. Statische Typen entsprechen dem mathematischen Begriff der Typentheorie, die Typentheorie in der Mathematik schränkt die Legalität einiger Ausdrücke einfach ein. Wie kann ich nicht 3 + [4,7] in Mathe sagen, dies ist wegen der Typentheorie davon.

Statische Typen sind daher keine Möglichkeit, Fehler aus theoretischer Sicht zu verhindern, sie sind eine Einschränkung der Grammatik. In der Tat, vorausgesetzt, dass +, 3 und Intervalle die üblichen festgelegten theoretischen Definitionen haben, wenn wir das Typsystem entfernen 3 + [4,7] hat ein ziemlich gut definiertes Ergebnis, das eine Menge ist. “Laufzeiterrors” gibt es theoretisch nicht, die praktische Anwendung des Typsystems besteht darin, Operationen zu verhindern, die für Menschen keinen Sinn ergeben. Operationen sind immer noch nur die Verschiebung und Manipulation von Bits.

Der Haken dabei ist, dass ein Typsystem nicht entscheiden kann, ob solche Operationen stattfinden oder nicht, wenn es ausgeführt werden soll. Wie in, genau die Menge aller möglichen Programme in diejenigen, die einen “Typ Fehler” haben, und diejenigen, die nicht sind. Es kann nur zwei Dinge tun:

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

Das könnte so aussehen, als würde ich mir selbst widersprechen. Aber was ein C- oder Java-Typ-Checker tut, ist, dass er ein Programm als “nichtgrammatisch” ablehnt oder es “Typerrors” nennt, wenn es bei 2 nicht erfolgreich ist. Es kann nicht beweisen, dass es nicht vorkommen wird. das bedeutet nicht, dass sie nicht auftreten werden, es bedeutet nur, dass es es nicht beweisen kann. Es kann sehr gut sein, dass ein Programm, das keinen Typerrors hat, einfach abgelehnt wird, weil es vom Compiler nicht bewiesen werden kann. Ein einfaches Beispiel ist, if(1) a = 3; else a = "string"; if(1) a = 3; else a = "string"; Da dieser Wert immer wahr ist, wird der else-Zweig niemals im Programm ausgeführt, und es sollte kein Typerrors auftreten. Aber es kann diese Fälle nicht allgemein beweisen, also wird es abgelehnt. Dies ist die Hauptschwäche vieler statisch typisierter Sprachen. Wenn Sie sich gegen sich selbst schützen, sind Sie notwendigerweise auch geschützt, wenn Sie sie nicht brauchen.

Aber entgegen der landläufigen Meinung gibt es auch statisch getippte Sprachen, die nach Prinzip 1 arbeiten. Sie lehnen einfach alle Programme ab, von denen sie beweisen können, dass sie einen Typerrors verursachen werden, und sie geben alle Programme weiter, von denen sie es nicht können. So ist es möglich, dass sie Programme zulassen, in denen Typerrors enthalten sind. Ein gutes Beispiel dafür ist Typed Racket, eine Mischung aus dynamischer und statischer Typisierung. Und einige würden argumentieren, dass Sie in diesem System das Beste aus beiden Welten bekommen.

Ein weiterer Vorteil der statischen Typisierung besteht darin, dass Typen zur Kompilierungszeit bekannt sind und der Compiler dies verwenden kann. Wenn wir in Java "string" + "string" oder 3 + 3 schreiben, stellen beide + -Token im Text am Ende eine völlig andere Operation und ein anderes Datum dar, der Compiler weiß, welche der Typen allein zu wählen sind.

Nun, ich werde hier eine sehr kontroverse Aussage machen, aber bedenken Sie: “Dynamisches Tippen” gibt es nicht .

Klingt sehr umstritten, aber es stimmt, dynamisch typisierte Sprachen sind aus einer theoretischen Perspektive untypisiert . Sie sind nur statisch typisierte Sprachen mit nur einem Typ. Oder einfach gesagt, es sind Sprachen, die in der Tat grammatikalisch durch eine kontextfreie Grammatik in der Praxis generiert werden.

Warum haben sie keine Typen? Da jede Operation für jeden Operanten definiert und erlaubt ist, was genau ist ein Laufzeiterrors? Es ist von einem theoretischen Beispiel rein ein Nebeneffekt . Wenn das print("string") das eine Zeichenkette druckt, eine Operation ist, dann ist die length(3) , die erstere hat den Nebeneffekt des Schreibens einer string in die Standardausgabe, letzteres einfach error: function 'length' expects array as argument. , das ist es. Aus theoretischer Perspektive gibt es keine dynamisch typisierte Sprache. Sie sind nicht typisiert

In Ordnung, der offensichtliche Vorteil der “dynamisch getippten” Sprache ist Ausdruckskraft, ein Typsystem ist nichts anderes als eine Begrenzung der Ausdruckskraft. Und im Allgemeinen würden Sprachen mit einem Typsystem tatsächlich ein definiertes Ergebnis für all jene Operationen haben, die nicht erlaubt sind, wenn das Typsystem einfach ignoriert würde, die Ergebnisse würden für Menschen einfach keinen Sinn ergeben. Viele Sprachen verlieren ihre Turing-Vollständigkeit, nachdem sie ein Typsystem angewendet haben.

Der offensichtliche Nachteil ist die Tatsache, dass Operationen auftreten können, die für den Menschen unsinnige Ergebnisse liefern würden. Um dagegen zu wappnen, definieren dynamisch typisierte Sprachen diese Operationen typischerweise neu, anstatt dieses unsinnige Ergebnis zu erzeugen, definieren sie es neu, um den Nebeneffekt des Schreibens eines Fehlers zu haben und möglicherweise das Programm insgesamt anzuhalten. Dies ist überhaupt kein “Fehler”, in der Tat impliziert die Sprachspezifikation dies normalerweise, dies ist ebenso ein Verhalten der Sprache wie das Drucken einer Zeichenkette 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, dass es passiert , auch in einigen Punkten für das Debuggen nützlich sein und zeigen, dass es überhaupt kein “Fehler” ist, sondern eine gut definierte Eigenschaft der Sprache. In der Tat schützt der einzige Überrest der “dynamischen Typisierung”, den die meisten Sprachen haben, gegen eine Division durch Null. Dies ist, was dynamische Typisierung ist, gibt es keine Typen, gibt es keine weiteren Typen als diese Null ist ein anderer Typ als alle anderen Zahlen. Was ein Typ als Typ bezeichnet, ist nur eine weitere Eigenschaft eines Datums, etwa die Länge eines Arrays oder das erste Zeichen eines Strings. Und viele dynamisch typisierte Sprachen erlauben Ihnen auch, Dinge wie "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 normalerweise in der Lage sind, sie zu prüfen und damit umzugehen und daraus zu entscheiden. Natürlich ist es in der Theorie 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, verwenden Sie nur einen Typ wie long long int und verwenden Sie die ersten 8 Bits, um Ihren ‘type’ zu speichern und functionen entsprechend zu schreiben, die danach suchen und float oder ganzzahlige Addition ausführen. Sie haben eine statisch typisierte Sprache mit einem Typ oder einer dynamischen Sprache.

In der Praxis zeigt dies alles, dass statisch typisierte Sprachen im Allgemeinen beim Schreiben kommerzieller Software verwendet werden, während dynamisch typisierte Sprachen dazu neigen, im Zusammenhang mit der Lösung einiger Probleme und der Automatisierung einiger Aufgaben verwendet zu werden. Das Schreiben von Code in statisch getippten Sprachen dauert einfach lang und ist umständlich, weil man Dinge nicht tun kann, von denen man weiß, dass sie gut ausgehen, aber das Typsystem schützt Sie immer noch vor sich selbst für Fehler, die Sie nicht machen. Viele Programmierer wissen nicht einmal, dass sie das tun, weil es in ihrem System ist, aber wenn Sie in statischen Sprachen programmieren, umgehen Sie oft die Tatsache, dass das Typsystem Sie nicht Dinge tun lässt, die nicht schiefgehen können, weil es kann nicht beweisen, dass es nicht schief geht.

Wie ich bemerkte, bedeutet “statisch getippt” im Allgemeinen Fall 2, schuldig, bis bewiesen wurde, dass es unschuldig ist. Aber einige Sprachen, die ihr Typsystem überhaupt nicht von der Typentheorie ableiten, verwenden Regel 1: Unschuldig bis bewiesene Schuld, was die ideale Hybride sein könnte. Vielleicht ist Typed Racket also etwas für dich.

Außerdem, für ein absurderes und extremeres Beispiel, implementiere ich gerade eine Sprache, bei der ‘Typen’ wirklich das erste Zeichen eines Arrays sind, sie sind Daten, Daten des ‘Typs’, ‘Typs’, 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.

Der vielleicht größte “Vorteil” der dynamischen Typisierung ist die flachere Lernkurve. Es gibt kein zu lernendes Typsystem und keine nicht-triviale Syntax für Eckfälle wie zum Beispiel Typbeschränkungen. Das macht dynamisches Tippen für viel mehr Menschen zugänglich und für viele Menschen, für die anspruchsvolle statische Systeme unerreichbar sind, durchführbar. Folglich hat sich die dynamische Typisierung in den Bildungskontexten (zB Scheme / Python am MIT) und domänenspezifischen Sprachen für Nicht-Programmierer (zB Mathematica ) durchgesetzt . Dynamische Sprachen haben sich auch in Nischen durchgesetzt, in denen sie wenig oder gar keine Konkurrenz haben (zB 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 entworfen wurden, deutlich prägnanter sein als die prägnantesten statisch getippten Sprachen (z. B. OCaml ) .

Die Hauptnachteile der dynamischen Typisierung sind:

  • Laufzeiterrors.

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

  • Keine vom Compiler verifizierte Dokumentation.

  • Schlechte performance (in der Regel zur Laufzeit, aber manchmal zur Kompilierungszeit, z. B. Stalin-Schema) und unvorhersehbare performance aufgrund der Abhängigkeit von anspruchsvollen Optimierungen.

Persönlich wuchs ich mit dynamischen Sprachen auf, aber ich würde sie nicht als Profi mit einer 40-Finger-Stange anfassen, es sei denn, es gäbe keine anderen realisierbaren Optionen.

Von Artimas Typisierung: stark vs. schwach, statisch vs. dynamisch Artikel:

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

Eine schwache Eingabe bedeutet, dass Sie Typen ohne explizite Konvertierung mischen können

In der Arbeit von Pascal Costanza, Dynamic vs. Static Typing – Eine musterbasierte Analyse (PDF), behauptet er, dass statische Typisierung in manchen Fällen errorsanfälliger ist als dynamische Typisierung. Einige statisch typisierte Sprachen zwingen Sie, die dynamische Typisierung manuell zu emulieren, um “The Right Thing” zu machen. Es wird bei Lambda the Ultimate diskutiert.

Es hängt vom Kontext ab. Es gibt viele Vorteile, die sowohl für dynamisch typisierte als auch für stark typisierte Systeme geeignet sind. Ich bin der Meinung, dass der Fluss der dynamischen Typen Sprache schneller ist. Die dynamischen Sprachen sind nicht durch classnattribute und Compiler eingeschränkt, die darüber nachdenken, was im Code vor sich geht. Du hast ein bisschen Freiheit. Außerdem ist die dynamische Sprache normalerweise ausdrucksstärker und führt zu weniger Code, der gut ist. Trotzdem ist es errorsanfälliger, was ebenfalls fragwürdig ist und mehr von der Unit-Test-Abdeckung abhängt. Es ist ein einfacher Prototyp mit dynamischer Sprache, aber Wartung kann zum Albtraum werden.

Der Hauptgewinn gegenüber dem statischen System ist IDE-Unterstützung und sicherlich ein statischer Code-Analysator. Sie werden nach jeder Änderung des Codes sicherer im Code. Die Wartung ist ein friedlicher Kuchen mit solchen Werkzeugen.

Es gibt viele verschiedene Dinge über statische und dynamische Sprachen. Für mich besteht der Hauptunterschied darin, dass in dynamischen Sprachen die Variablen 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 Performanceschub, aber moderne JITs kommen dem besten, was Sie mit der Optimierung von statischen Compilern erreichen können, unglaublich nahe. (in einigen Randfällen, sogar besser als das).

Es geht um das richtige Werkzeug für den Job. In 100% der Fälle ist es nicht besser. Beide Systeme wurden vom Menschen geschaffen und haben Fehler. Entschuldigung, aber wir saugen und machen perfekte Sachen.

Ich mag dynamisches Tippen, weil es mir aus dem Weg geht, aber ja Laufzeiterrors können sich einschleichen, die ich nicht geplant habe. Wo statische Typisierung die oben genannten Fehler beheben kann, aber einen Anfänger (in typisierten Sprachen) Programmierer verrückt machen versucht, zwischen einem konstanten Zeichen und einer Zeichenfolge zu wechseln.

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.

für Beispiel int x; x = 10;

System.out.println (x);

Dynamisches Schreiben: 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