Ich sehe hier einige interessante Diskussionen über statische und dynamische Typisierung. Ich bevorzuge im Allgemeinen die statische Typisierung aufgrund der Überprüfung des Kompiliertyps, besser dokumentierten Codes usw. Ich stimme jedoch zu, dass sie den Code überladen, wenn sie beispielsweise so ausgeführt werden, wie Java es tut.
Ich bin also dabei, eine eigene funktionale Stilsprache zu erstellen, und Typinferenz ist eines der Dinge, die ich implementieren möchte. Ich verstehe, dass es ein großes Thema ist, und ich versuche nicht, etwas zu erschaffen, was vorher noch nicht getan wurde, sondern nur grundlegende Schlussfolgerungen ...
Irgendwelche Hinweise, was ich lesen soll, die mir dabei helfen? Am liebsten etwas pragmatischeres / praktischeres als theoretischere kategorietheoretische / typentheoretische Texte. Wenn es da draußen einen Implementierungstext mit Datenstrukturen / Algorithmen gibt, wäre das einfach schön.
Antworten:
Ich fand die folgenden Ressourcen hilfreich, um die Typinferenz in der Reihenfolge zunehmender Schwierigkeiten zu verstehen:
Da der beste Weg zu lernen darin besteht, dies zu tun, empfehle ich dringend, eine Typinferenz für eine Spielzeugfunktionssprache zu implementieren, indem Sie eine Hausaufgabe eines Programmiersprachenkurses durcharbeiten.
Ich empfehle diese beiden zugänglichen Hausaufgaben in ML, die Sie beide in weniger als einem Tag erledigen können:
Diese Aufgaben stammen aus einem fortgeschritteneren Kurs:
MiniML implementieren
Polymorphe, existentielle, rekursive Typen (PDF)
Bidirektionales Typechecking (PDF)
Untertypisierung und Objekte (PDF)
quelle
Es ist bedauerlich, dass ein Großteil der Literatur zu diesem Thema sehr dicht ist. Ich war auch in deinen Schuhen. Ich habe meine erste Einführung in das Thema von Programmiersprachen: Anwendungen und Interpretation bekommen
http://www.plai.org/
Ich werde versuchen, die abstrakte Idee zusammenzufassen, gefolgt von Details, die ich nicht sofort offensichtlich fand. Zunächst kann an eine Typinferenz gedacht werden, um Einschränkungen zu generieren und dann zu lösen. Um Einschränkungen zu generieren, durchlaufen Sie den Syntaxbaum und generieren eine oder mehrere Einschränkungen für jeden Knoten. Wenn der Knoten beispielsweise ein
+
Operator ist, müssen die Operanden und die Ergebnisse alle Zahlen sein. Ein Knoten, der eine Funktion anwendet, hat denselben Typ wie das Ergebnis der Funktion usw.Für eine Sprache ohne
let
können Sie die oben genannten Einschränkungen blind durch Ersetzen lösen. Beispielsweise:Hier können wir sagen, dass die Bedingung der if-Anweisung boolesch sein muss und dass der Typ der if-Anweisung mit dem Typ ihrer
then
undelse
-Klauseln identisch ist . Da wir Zahlen kennen1
und2
sind, wissen wir durch Substitution, dass dieif
Aussage eine Zahl ist.Wo die Dinge böse werden und was ich eine Weile nicht verstehen konnte, ist das Thema:
Hier haben wir uns an
id
eine Funktion gebunden , die alles zurückgibt, was Sie übergeben haben, auch bekannt als Identitätsfunktion. Das Problem ist, dass der Typ des Funktionsparametersx
bei jeder Verwendung von unterschiedlich istid
. Die zweiteid
ist eine Funktion vom Typa -> a
, woa
alles sein kann. Der erste ist vom Typ(a -> a) -> (a -> a)
. Dies ist als Let-Polymorphismus bekannt. Der Schlüssel besteht darin, Einschränkungen in einer bestimmten Reihenfolge zu lösen: Lösen Sie zuerst Einschränkungen für die Definition vonid
. Das wird seina -> a
. Dann können frische, separate Kopien des Typs vonid
in die Einschränkungen für jeden Ortid
eingesetzt werden, zum Beispiela2 -> a2
unda3 -> a3
.Das wurde in Online-Ressourcen nicht ohne weiteres erklärt. Sie werden den Algorithmus W oder M erwähnen, aber nicht, wie sie beim Lösen von Einschränkungen funktionieren oder warum der Let-Polymorphismus nicht beeinträchtigt wird: Jeder dieser Algorithmen erzwingt eine Reihenfolge beim Lösen der Einschränkungen.
Ich fand diese Ressource äußerst hilfreich, um Algorithmus W, M und das allgemeine Konzept der Erzeugung und Lösung von Einschränkungen miteinander zu verknüpfen. Es ist ein wenig dicht, aber besser als viele:
http://www.cs.uu.nl/research/techreps/repo/CS-2002/2002-031.pdf
Viele der anderen Papiere dort sind auch nett:
http://people.cs.uu.nl/bastiaan/papers.html
Ich hoffe, das hilft, eine etwas trübe Welt zu klären.
quelle
Neben Hindley Milner für funktionale Sprachen ist ein weiterer beliebter Ansatz zur Typinferenz für dynamische Sprachen
abstract interpretation
.Die Idee der abstrakten Interpretation besteht darin, einen speziellen Interpreter für die Sprache zu schreiben, anstatt eine Umgebung mit konkreten Werten (1, falsch, Abschluss) beizubehalten. Sie arbeitet mit abstrakten Werten, auch bekannt als Typen (int, bool usw.). Da das Programm auf abstrakten Werten interpretiert wird, wird es als abstrakte Interpretation bezeichnet.
Pysonar2 ist eine elegante Implementierung der abstrakten Interpretation für Python. Es wird von Google zur Analyse von Python-Projekten verwendet. Grundsätzlich wird
visitor pattern
der Bewertungsaufruf an den relevanten AST-Knoten gesendet. Die Besucherfunktiontransform
akzeptiert dencontext
aktuellen Knoten, der ausgewertet wird, und gibt den Typ des aktuellen Knotens zurück.quelle
Typen und Programmiersprachen von Benjamin C. Pierce
quelle
Lambda the Ultimate beginnt hier .
quelle