Mit welcher Sprache kann der durchschnittliche Programmierer Ihrer Meinung nach Funktionen mit der geringsten Anzahl schwer zu findender Fehler ausgeben? Dies ist natürlich eine sehr breite Frage, und ich interessiere mich für sehr breite und allgemeine Antworten und Weisheiten.
Persönlich verbringe ich sehr wenig Zeit damit, nach seltsamen Fehlern in Java- und C # -Programmen zu suchen, während C ++ - Code einen eigenen Satz von wiederkehrenden Fehlern aufweist und Python / similar einen eigenen Satz von allgemeinen und albernen Fehlern aufweist, die vom Compiler erkannt würden in anderen Sprachen.
Außerdem fällt es mir schwer, funktionale Sprachen in dieser Hinsicht zu berücksichtigen, da ich noch nie ein großes und komplexes Programm gesehen habe, das in vollständig funktionalem Code geschrieben ist. Ihre Eingabe bitte.
Bearbeiten: Vollständig willkürliche Klärung schwer auffindbarer Fehler: Die Reproduktion dauert mehr als 15 Minuten, und die Suche nach Ursachen und deren Behebung dauert mehr als 1 Stunde.
Verzeihen Sie mir, wenn dies ein Duplikat ist, aber ich habe zu diesem bestimmten Thema nichts gefunden.
quelle
Antworten:
Je leistungsfähiger das Typsystem der Sprache ist, desto mehr Fehler werden zur Kompilierungszeit selbst abgefangen.
Die folgende Abbildung vergleicht einige der bekannten Programmiersprachen hinsichtlich der Leistungsfähigkeit, Einfachheit und Sicherheit ihrer Typsysteme. [ Quelle ]
* Berücksichtigung der Fähigkeit, unsichere Konstrukte zu verwenden.
quelle
(let ((itbe '())) ... )
...Meiner Meinung nach hilft Ihnen Haskell dabei, einige häufige Fehlerquellen zu vermeiden:
null
gehört nicht zu den Werttypdefinitionen: Auf diese Weise vermeiden Sie den Milliarden-Dollar-Fehlerquelle
null
gibt, gibt esundefined
, die ein Mitglied jeder Art ist.)Die am schwersten zu findenden Fehler sind traditionell die Race-Bedingungen in Multithread-Anwendungen
Daher brauchen Sie Sprachen, die den Parallismus für Sie so weit und unauffällig wie möglich beherrschen. Diese sind noch nicht Mainstream. Java erledigt einige Aufgaben, überlässt Ihnen jedoch den schwierigen Teil.
Meines Erachtens brauchen Sie eine funktionierende Sprache, da "keine Nebenwirkungen" die beiden Aufzählungspunkte erst einmal verschwinden lassen. Ich habe gesehen, dass die Arbeit daran, Haskell zu einer effizienten Multithread-Sprache zu machen, fortgesetzt wird, und ich glaube, dass Fortress von Grund auf als effiziente Parallelsprache konzipiert wurde.
Bearbeiten: In Java
Executors
behandeln noch mehr der harten Teile. Sie müssen die einzelnen Aufgaben an dieCallable
Benutzeroberfläche anpassen .quelle
Ada ist so konzipiert, dass möglichst viel zur Kompilierungszeit und nicht zur Laufzeit abgefangen wird. Dies bedeutet, dass das Kompilieren eines Programms in Ada oft etwa 10-mal länger dauert als in Java, aber wenn es kompiliert wird, können Sie sicherer sein, dass sich ganze Klassen von Fehlern nicht manifestieren, wenn das Programm ausgeführt wird Lauf.
quelle
Zunächst eine Definition: Ein schwer zu findender Fehler ist, wie ich es verstehe, ein Fehler, der reproduziert werden kann, dessen Ursache jedoch schwer zu finden ist.
Der wahrscheinlich wichtigste Aspekt ist das, was ich Enge nennen würde , dh wie weit kann ein Fehler entkommen, wie groß ist der Umfang, den ein Fehler möglicherweise beeinflussen kann. In Sprachen wie C kann ein Fehler, z. B. ein negativer Array-Index oder ein nicht initialisierter Zeiger, buchstäblich alles im gesamten Programm betreffen. Im schlimmsten Fall müssen Sie also überall nach der Ursache des Problems suchen.
Gute Sprachen in dieser Hinsicht unterstützen Zugriffsmodifikatoren und erzwingen sie auf eine Weise, die es schwierig oder unmöglich macht, sie zu umgehen. Gute Sprachen ermutigen Sie, den Umfang Ihrer Variablen einzuschränken, anstatt es zu einfach zu machen, globale Variablen zu haben (z. B. "alles, was nicht explizit deklariert wird, ist eine globale Variable mit einem Standardtyp und -wert").
Der zweite wichtige Aspekt ist die Parallelität . Die Rennbedingungen sind im Allgemeinen schwer zu reproduzieren und daher schwer zu finden. Gute Sprachen bieten benutzerfreundliche Synchronisationsmechanismen, und ihre Standardbibliotheken sind bei Bedarf threadsicher.
Dies vervollständigt bereits meine Liste; andere Dinge wie das starke Tippen helfen dabei, Fehler beim Kompilieren zu finden, aber diese Fehler wären wahrscheinlich später nicht schwer zu finden.
In Anbetracht dessen würde ich sagen, dass Java und C # sowie viele andere Sprachen in der JVM- und .net-Welt geeignet sind, um schwer zu findende Fehler zu vermeiden.
quelle
Da Excel das am häufigsten verwendete DSL ist, werde ich mich für Excel entscheiden. (natürlich ohne VBA)
Es passt die Rechnung:
quelle
123
oderABC
) oder als Funktion (=SUM(A2:A5)
) festgelegt. Excel wertet dann alle Variablen aus, um herauszufinden, in welcher Reihenfolge Abhängigkeiten gelöst werden sollen usw. Es handelt sich sicherlich nicht nur um Daten.Dies ist eine schwierige Frage, da die meisten Fehler nicht von der Sprache selbst verursacht werden, sondern von Entwicklern, die Fehler bei der Verwendung der Sprache machen.
Ich glaube, es gibt verschiedene Aspekte von Sprachfunktionen, die die Wahrscheinlichkeit von Fehlern beeinflussen:
Interaktivität - Dynamische Sprachen mit REPLs fördern die Interaktion / das Experimentieren mit laufenden Programmen und viel kleineren Code- / Testzyklen. Wenn Sie der Meinung sind, dass Iteration eine gute Möglichkeit ist, saubere und einfache Lösungen zu finden und Fehler zu erkennen / zu beseitigen, ist dies in der Regel für interaktive Sprachen von Vorteil.
Expressivität - Wenn der Code kürzer ist und weniger Boilerplate / zufällige Komplexität aufweist, ist es einfacher, Bugs / Logikfehler zu erkennen.
Typensicherheit - Je mehr Kompilierungszeit überprüft wird, desto mehr Fehler werden vom Compiler abgefangen. Im Allgemeinen ist Typensicherheit also eine gute Sache. Allerdings sind diese Fehler normalerweise nicht schwer zu finden - selbst in einer volldynamischen Sprache führt der falsche Typ in einer Datenstruktur normalerweise zu einem sehr offensichtlichen Laufzeitfehler, und TDD erkennt diese Fehler fast immer.
Unveränderlichkeit - Viele schwere Fehler sind auf komplexe Wechselwirkungen des veränderlichen Zustands zurückzuführen. Sprachen, die Unveränderlichkeit betonen (Haskell, Clojure, Erlang), haben einen enormen Vorteil, indem sie Veränderlichkeit vermeiden
Funktionale Programmierung - funktionale Ansätze zum Schreiben von Code sind in der Regel "beweisbarer" als objektorientierter Code mit komplexen Folgen von Effekten / Interaktionen. Ich habe die Erfahrung gemacht, dass FP dabei hilft, knifflige Fehler zu vermeiden. Ich glaube, dass es irgendwo akademische Forschungen gibt, die ich derzeit nicht finden kann.
Parallelitätsunterstützung - Parallelitätsprobleme sind besonders schwer zu erkennen und zu beheben, weshalb dies so wichtig ist. Alles, was manuelles Sperren erfordert, ist letztendlich zum Scheitern verurteilt (und dies schließt so ziemlich jeden objektorientierten Ansatz zur Parallelität ein). Die beste Sprache, die ich in dieser Hinsicht kenne, ist Clojure - es verfügt über einen einzigartigen Ansatz zum Verwalten der Parallelität, der Software-Transaktionsspeicher mit unveränderlichen Datenstrukturen kombiniert, um ein neues, zuverlässiges und zusammensetzbares Parallelitäts-Framework zu erhalten. Siehe http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey für mehr Einblicke
quelle
Je weniger mächtig eine Sprache ist, desto weniger Möglichkeiten bietet sie Ihnen, Ihren eigenen Fuß zu schießen.
Hochsprachen wie Java und C # verursachen weniger Fehler als Niedrigsprachen wie C ++.
Allerdings glaube ich, dass Java sicherer ist als C #. Java ist künstlich begrenzt, so dass ein durchschnittlicher Programmierer ohne fortgeschrittene Kenntnisse es beherrschen und stabile Programme erstellen kann.
quelle
Meiner Meinung nach Delphi. Da die Sprache auf Pascal basiert, ist sie für den durchschnittlichen Programmierer (oder auch für unerfahrene Programmierer) einfach und intuitiv genug , um leicht gefunden zu werden, und dank ihrer umfangreichen Tool- und Bibliotheksunterstützung sind die meisten Fehler leicht zu finden.
if (alert = RED) {LaunchNukes;}
wird beispielsweise nicht kompiliert.)quelle
var I: Integer; Pointer(I)^ := $00;
Eine Sache, die berücksichtigt werden muss, ist die Bearbeitungszeit.
In den letzten fünf Jahren habe ich hauptsächlich Webanwendungen in Java (JSF, Seam usw.) entwickelt. Vor kurzem habe ich einen neuen Job bekommen und wir verwenden Perl (mit Catalyst und Moose).
In Perl bin ich viel produktiver als in Java.
Nicht kompilieren und (Hot-) Deployen zu müssen, ist ein Grund. Ich finde auch, dass das Schreiben von Use Cases einfacher ist, da es iterativer durchgeführt werden kann. Und die Frameworks in Java scheinen unnötig komplex zu sein, zumindest für die Projekte, an denen ich beteiligt war.
Ich denke, die Anzahl der Fehler in meinem Perl-Code ist mehr oder weniger die gleiche wie die Anzahl der Fehler in meinem Java-Code, sie könnte sogar höher sein. Aber ich finde es einfacher und schneller, diese Fehler zu finden und zu beheben.
quelle
Ein Überblick über die Anzahl der Tools, die für die statische und dynamische Code-Analyse für jede Programmiersprache verfügbar sind, könnte eine Idee liefern. Je mehr Tools für eine Sprache verfügbar sind, desto wahrscheinlicher ist es, dass die Sprache entweder bei Benutzern sehr beliebt ist oder bei der Erzeugung schwer zu findender Fehler sehr beliebt ist. Es ist mir jedoch nicht möglich, Google auf eine Studie zu diesem Thema aufmerksam zu machen. Es sollte auch beachtet werden, dass einige Sprachen wie C verwendet werden können, um die zugrunde liegenden Hardwarefehler zu umgehen, sowie um den Verschleiß der Hardware mit zunehmendem Alter zu umgehen.
quelle
Anstatt über Sprachen zu sprechen, sollten Sie über Sprachmerkmale sprechen
quelle