Auf meiner Suche nach Forschungsarbeiten über Typensysteme für imperative Sprachen finde ich nur Lösungen für eine Sprache mit veränderlichen Referenzen, aber ohne echte imperative Kontrollstrukturen wie zusammengesetzte Operatoren, Schleifen oder Bedingungen.
Es ist also nicht klar, wie eine imperative Sprache mit partieller Typinferenz wie http://rust-lang.org implementiert werden kann.
In den Veröffentlichungen werden parametrisierte Typen nicht erwähnt, z. B. List of a
weil parametrisierte Typen eine triviale Erweiterung des Hindley-Milner-Typsystems darstellen. Nur der Vereinigungsalgorithmus sollte erweitert werden, und der Rest der Inferenz funktioniert unverändert. Zuweisungen können jedoch nicht trivial hinzugefügt werden, da Paradoxe auftreten. Daher müssen spezielle Techniken wie die Einschränkung des ML-Werts angewendet werden.
Können Sie Artikel oder Bücher empfehlen, die ein Typensystem für eine Sprache mit Imperativschleifen, Bedingungen, E / A und zusammengesetzten Anweisungen beschreiben?
quelle
let val x = ref 9 in while !x>0 do (print (Int.toString (!x)); x := !x-1) end
. Ist die Antwort, die Sie auf der Ebene einer Forschungsfrage suchen, "Anwenden von in Caml / SML entwickelten Techniken, einschließlich der Werteinschränkung"?Antworten:
Wenn Sie nach einer ordentlichen, funktionalen Referenz zur Typinferenz suchen, bin ich ein bisschen parteiisch gegenüber Gundry, McBride und McKinnas 2010 "Typinferenz im Kontext ", obwohl dies möglicherweise kein guter Leitfaden für tatsächlich vorhandene Implementierungen ist .
Ich denke, ein Teil der Antwort ist, dass es jenseits der Wertebeschränkung wirklich nicht so schwierig ist, die Inferenz des Hindley-Milner-Typs an imperative Sprachen anzupassen: Wenn Sie
e1; e2
als syntaktischen Zucker für(fn _ => e2) e1
undwhile e1 do e2
als syntaktischen Zucker für definierenwhiledo e1 (fn () => e2)
, wowhiledo
ist ein regulärer rekursive Funktiondann wird alles gut funktionieren, einschließlich Typinferenz.
Was die Wertebeschränkung betrifft, die eine spezielle Technik ist, mag ich die folgende Geschichte; Ich bin mir ziemlich sicher, dass ich es von Karl Crary abgeholt habe. Betrachten Sie den folgenden Code, den Sie aufgrund der Werteinschränkung nicht in ML schreiben können:
Vergleichen Sie es mit dem folgenden Code, der völlig unproblematisch ist:
Wir wissen , was das zweite Beispiel macht: es schafft zwei neue ref Zellen enthält
NONE
, dann setztSOME 5
in der ersten (einint option ref
), dann setztSOME "Hello"
in der zweiten (astring option ref
).x
x
x
Dies würde darauf hinweisen, dass ein "gutes" Verhalten des ersten Beispiels darin besteht, sich genauso zu verhalten wie das zweite Beispiel - das Lambda auf Typebene zwei verschiedene Male instanziieren. Das erste Mal instanziieren wir
x
mitint
, was dazu führt, dassx [int]
eine Referenzzelle gehalten wirdNONE
und dannSOME 5
. Das zweite Mal instanziieren wirx
mitstring
, wasx [string]
zu einem ( anderen! ) Referenzzellen-Holding führen wirdNONE
und dannSOME "Hello"
. Dieses Verhalten ist "korrekt" (typsicher), aber es ist definitiv nicht das, was ein Programmierer erwarten würde, und deshalb haben wir die Wertbeschränkung in ML, um zu vermeiden, dass Programmierer mit dieser unerwarteten Art von Verhalten umgehen.quelle
e1; e2
enthält eine nicht übereinstimmende Klammer und ein Semikolon (das definiert werden soll). Meinten Sie(fn _ => e2) e1
?Die Doktorarbeit von Xavier Leroy ist ein guter Anfang.
quelle
Es tut mir leid, dass ich meine eigene Frage beantwortet habe, aber die fragliche Referenz ist
Ein Vorschlag für Standard ML , Milner, 1983
Teil 6 "Standard Derived Forms" befasst sich ziemlich ausführlich mit dem Desugaring von imperativen Konstrukten. Und bis jetzt ist es die früheste Referenz dieser weitgehend offensichtlichen Transformationen, die ich finden konnte.
quelle