web-dev-qa-db-ja.com

インタープリターを作成するとき、型推論アルゴリズムは解析されたASTをどのように変更すべきですか?それをすべきですか?

インタプリタを書くとき、型推論アルゴリズムはどのように構文解析されたASTにチャンスを与えるべきですか? または解析と推論は必ずしも同時に行われますか?

強く型付けされた関数型言語インタープリターを実装しました。このインタープリターでは、各関数を1回だけ宣言できます(つまり、署名のバリアントはありません)。型指定されていない実装パーサーが完成して機能するようになり次第、パーサーの結果のASTから供給される型推論アルゴリズムを作成しました。

Hindley-Damas-Milnerはチャームのように機能していますが、プログラムはそれを使用し、型チェックに合格すると、問題を忘れて合格します。 ASTインタプリタへ。今のところ、「ターゲット言語」(つまり、インタプリタが書かれている言語)はインタプリタタイプのニーズを満たしていますが、疑問に思っています)このアプローチが通常の場合:「ok」の結果の後にすべての型推論の結果を破棄します。

また、インタプリタの代わりにコンパイラを作成することで、この違いは何か違いがありますか?

4
viyps

いいえ、良い分析結果を捨てることは絶対に普通ではありません。明確な違いについては、Scalaコンパイラを確認してください。これは実行フェーズに基づいており、特定のフェーズの後に実行されるプラグインを追加できます。プラグインを配置することは特に興味深いですタイピングフェーズの後、これは推論されたタイプのすべてを非常に便利な方法で提供するためです。

ただし、ASTはchangedannotatedほど多くありません。 ASTに保持されているステートメント、式、関数定義などの基本構造は、もちろん変更されません。型推論中に実際に行うことは、ツリーノードに注釈を付けることです。それぞれのタイプ。

たとえば、推論を入力する前に、ASTが関数fの関数ノードにあり、AST内のどこかにあり、子を持っていますノード。引数やステートメント/式に似ています。型の推論中に、これらの子ノードの型、つまりステートメント/式の型を決定し、それらから関数fの型を決定します。これで、fintを返し、intが使用される場所でのみ使用されますが、この情報を失う理由はありません。

インタープリターとコンパイラーに関しては、ASTに注釈を付けた型を使用することには大きな利点があり、それをはるかに超えています。たとえばIDEを考えてみてください。プラグインの作成者は、型注釈付きのASTを使用できることを非常に感謝しています。単純にknowを使用する方がはるかに効率的で、fint 、型補完をもう一度実行する必要がなく、コード補完を実装する場合。

ある時点で言語を拡張したい場合があります。拡張が型推論を超えている場合、通常はその結果に依存する必要があります。たとえば、タイプセーフなマクロやある種のセマンティックチェックを追加することを検討してください。

要約:強く型付けされた言語の型情報は非常に重要であるため、結果を破棄するためだけに型推論を実行すると、冒とくに似ています。自分や他の人から情報を奪い、利用可能な場合は非常に強力であり、生成にコストがかかります。

6
Frank