Um diese Aussage zu verstehen, müssen wir zunächst verstehen, was uns ein statisches Typensystem einkauft. Im Grunde ist das, was uns ein statisches Typsystem bietet, eine Garantie: Wenn der Programmtyp überprüft wird, kann eine bestimmte Klasse von Laufzeitverhalten nicht auftreten.
Das klingt bedrohlich. Nun, ein Typprüfer ähnelt einem Theoremprüfer. (Nach dem Curry-Howard-Isomorphismus sind sie dasselbe.) Eine Besonderheit bei Theoremen ist, dass Sie, wenn Sie einen Theorem beweisen, genau beweisen, was der Theorem sagt, nicht mehr. (Das ist zum Beispiel der Grund, warum, wenn jemand sagt "Ich habe dieses Programm als richtig erwiesen", Sie immer fragen sollten "Bitte definieren Sie" richtig ".) Dasselbe gilt für Typsysteme. Wenn wir sagen "ein Programm ist typsicher", meinen wir nicht, dass kein möglicher Fehler auftreten kann. Wir können nur sagen, dass die Fehler, die das Typensystem zu verhindern verspricht, nicht auftreten können.
Programme können also unendlich viele verschiedene Laufzeitverhalten haben. Von diesen sind unendlich viele nützlich, aber auch unendlich viele sind "falsch" (für verschiedene Definitionen von "Korrektheit"). Mit einem statischen Typsystem können wir nachweisen, dass ein bestimmter endlicher, fester Satz von unendlich vielen falschen Laufzeitverhalten nicht auftreten kann.
Der Unterschied zwischen verschiedenen Typsystemen besteht grundsätzlich darin, in welchen, wie vielen und wie komplexen Laufzeitverhalten sie sich als nicht vorkommend erweisen können. Schwache Systeme wie das von Java können nur sehr grundlegende Dinge beweisen. Beispielsweise kann Java beweisen, dass eine Methode, die als "returning a" eingegeben wurde, String
kein "return a" zurückgeben kann List
. Aber zum Beispiel kann es nicht beweisen, dass die Methode nicht zurückkehrt. Es kann auch nicht nachgewiesen werden, dass die Methode keine Ausnahme auslöst. Und es kann nicht beweisen, dass es nicht das Falsche zurückgibt String
- jedes String
wird die Typprüfung erfüllen. (Und natürlich, auch null
wird es genügen auch.) Es gibt auch ganz einfache Dinge , dass Java nicht beweisen können, weshalb wir Ausnahmen haben wie ArrayStoreException
, ClassCastException
oder jedermanns Liebling, der NullPointerException
.
Leistungsstärkere Typsysteme wie Agda's können auch Dinge wie "die Summe der beiden Argumente zurückgeben" oder "die sortierte Version der als Argument übergebenen Liste zurückgeben" beweisen.
Was die Entwickler von Elm unter der Aussage verstehen, dass sie keine Laufzeitausnahmen haben, ist, dass das Typsystem von Elm das Fehlen (eines signifikanten Teils) von Laufzeitverhalten nachweisen kann, das in anderen Sprachen nicht nachgewiesen werden kann und daher möglicherweise nicht auftritt zu fehlerhaftem Verhalten zur Laufzeit (was im besten Fall eine Ausnahme bedeutet, im schlimmsten Fall einen Absturz und im schlimmsten Fall überhaupt keinen Absturz, keine Ausnahme und nur ein stillschweigend falsches Ergebnis).
So sind sie nicht sagen : „Wir implementieren keine Ausnahmen“. Sie sagen, "Dinge, mit denen Laufzeitausnahmen in typischen Sprachen, mit denen typische Programmierer bei Elm Erfahrung haben würden, vom Typensystem erfasst werden". Natürlich wird jemand, der aus Idris, Agda, Guru, Epigramm, Isabelle / HOL, Coq oder ähnlichen Sprachen kommt, Elm im Vergleich als ziemlich schwach ansehen. Die Anweisung richtet sich eher an typische Java-, C♯-, C ++ -, Objective-C-, PHP-, ECMAScript-, Python-, Ruby-, Perl- usw. Programmierer.