Ich mag alles, was Kompilierungszeit ist, und ich mag die Idee, dass, sobald Sie ein Programm kompilieren, eine Menge Garantien für dessen Ausführung gegeben werden. Im Allgemeinen scheint ein statisches Typsystem (Haskell, C ++, ...) stärkere Kompilierungszeitgarantien zu bieten als jedes dynamische Typsystem.
Soweit ich weiß, geht Ada in Bezug auf die Überprüfung der Kompilierungszeit noch weiter und kann vor der Ausführung eine größere Anzahl von Fehlern erkennen. Es wird auch als ziemlich sicher angesehen, da es zu einem bestimmten Zeitpunkt für heikle Felder ausgewählt wurde (wenn Programmierfehler Menschenleben kosten können).
Nun frage ich mich: Wenn stärkere statische Garantien zu mehr dokumentiertem und sichererem Code führen, warum untersuchen wir dann nicht mehr in diese Richtung?
Ein Beispiel für etwas, das zu fehlen scheint, wäre eine Sprache, in der anstelle eines generischen int
Typs, dessen Bereich durch die Anzahl der Bits der zugrunde liegenden Architektur bestimmt wird, Bereiche definiert werden könnten (im folgenden Beispiel Int [a..b]
wird ein ganzzahliger Typ zwischen zwei angegeben) a und b enthalten):
a : Int [1..24]
b : Int [1..12]
a + b : Int [2..36]
a - b : Int [-11..23]
b - a : Int [-23..11]
oder (dies von Ada nehmen):
a : Int [mod 24]
b : Int [mod 24]
a + b : Int [mod 24]
Diese Sprache würde den besten zugrunde liegenden Typ für den Bereich auswählen und eine Überprüfung der Kompilierzeit für die Ausdrücke durchführen. So ist zum Beispiel gegeben:
a : Int [-3..24]
b : Int [3..10]
dann:
a / b
wird niemals nicht definiert.
Dies ist nur ein Beispiel, aber ich habe das Gefühl, dass wir beim Kompilieren noch viel mehr durchsetzen können. Also, warum scheint es so wenig Forschung zu diesem Thema zu geben? Welche Fachbegriffe beschreiben diese Idee (damit ich weitere Informationen zu diesem Thema finden kann)? Was sind die Grenzen?
dependent type
oderrefinement type
.Antworten:
Ich bin nicht in der Lage , wie viel zu sagen , mehr Forschung sollte zu dem Thema durchgeführt werden, aber ich kann Ihnen sagen , dass es ist Forschung getan werden, zum Beispiel des Verisoft XT Programm der Deutsch Regierung finanziert.
Die Konzepte, nach denen Sie meines Erachtens suchen, werden als formale Verifizierung und vertragsbasierte Programmierung bezeichnet , wobei letztere eine programmiererfreundliche Möglichkeit darstellt, die erste zu erstellen. Bei der vertragsbasierten Programmierung schreiben Sie zunächst Ihren Code wie gewohnt und fügen dann sogenannte Verträge in den Code ein. Eine leicht verwendbare Sprache, die auf diesem Paradigma basiert, ist Spec # von Microsoft Research und die funktional ähnliche, aber etwas weniger hübsche Code Contracts- Erweiterung für C #, die Sie beide online ausprobieren können (ähnliche Tools für andere Sprachen finden Sie unter rise4fun) ). Der von Ihnen erwähnte "int with range type" würde sich in zwei Verträgen in einer Funktion widerspiegeln:
Wenn Sie diese Funktion aufrufen möchten, müssen Sie Parameter verwenden, die diese Kriterien erfüllen. Andernfalls tritt ein Fehler bei der Kompilierung auf. Bei den oben genannten Verträgen handelt es sich um sehr einfache Verträge. Sie können nahezu jede Annahme oder Anforderung zu Variablen oder Ausnahmen und deren Beziehung einfügen, die Sie sich vorstellen können, und der Compiler prüft, ob jede Anforderung durch eine Annahme oder eine zu sichernde, dh ableitbare Bedingung abgedeckt ist aus den Annahmen. Daher kommt der Name: Der Angerufene stellt Anforderungen , der Anrufer stellt sicher, dass diese erfüllt werden - wie in einem Geschäftsvertrag.
In Bezug auf die Grenzen der allgemeinen Idee:
Eine letzte erwähnenswerte Sache, die nicht ganz der obigen Erklärung entspricht, ist ein Feld namens "Implizite Komplexitätstheorie", zum Beispiel dieses Papier . Es zielt darauf ab, Programmiersprachen zu charakterisieren, in denen jedes Programm, das Sie schreiben können, einer bestimmten Komplexitätsklasse zuzuordnen ist, beispielsweise P. In einer solchen Sprache wird automatisch sichergestellt, dass jedes von Ihnen geschriebene Programm eine polynomielle Laufzeit hat, die "überprüft" werden kann. beim kompilieren einfach das programm kompilieren. Ich kenne jedoch keine praktisch verwertbaren Ergebnisse dieser Forschung, bin aber auch weit davon entfernt, ein Experte zu sein.
quelle