web-dev-qa-db-ja.com

STGを理解する

GHCの設計は、「スパインレス、タグレスGマシン」の略であるSTGと呼ばれるものに基づいています。

現在、G-machineは、怠惰の実装方法を定義する「グラフ還元マシン」の略です。評価されていないサンクは式ツリーとして格納され、プログラムの実行にはreducingこれらを通常の形式に変換する必要があります。 (A treeは非巡回グラフですが、Haskellの広範な再帰は、Haskell式が一般的なgraphsを形成することを意味します。したがって、グラフ還元であり、ツリー還元ではありません。)

あまり明確ではないのは、「スパインレス」と「タグレス」という用語です。

  1. I think「スパインレス」とは、関数適用に関数適用ノードの「スパイン」がないことを指します。代わりに、呼び出された関数に名前を付け、そのすべての引数を指すオブジェクトがあります。あれは正しいですか?

  2. 「タグレス」とは、コンストラクターノードがコンストラクターIDで「タグ付け」されていないことを指し、代わりに大文字と小文字の表現はジャンプ命令を使用して解決されると思いました。しかし、今はそれが正しいかどうかわかりません。代わりに、ノードが評価状態でタグ付けされていないという事実を参照しているようです。これらの解釈のどれが正しいか(もしあれば)誰かが明確にすることができますか?

43
27

私が正しければ、あなたは「スパインレス」について正しいです。これは基本的に、Burn、Peyton-Jones、Robsonによる1988年の記事「TheSpinelessG-Machine」で説明されています。私はそれを読みました、しかしそれは私の心の中でそれほど新鮮ではありません。基本的に、Gマシンでは、式の先頭を指す上部のノードを除いて、すべてのスタックエントリがアプリケーションノードを指します。これらのアプリケーションノードは引数に間接的にアクセスし、一部のG-Machineの説明では、関数を適用する前にスタックが再配置されるため、スタックの最後のnノードはアプリケーションノードではなく引数を指すようになります。私が誤解しない限り、「スパインレス」の部分は、これらのアプリケーションノード(グラフのスパインと呼ばれる)をスタックに完全に配置しないようにすることです。したがって、各削減の前にその再配置を回避します。

「タグレス」の部分に関しては、以前はより正確ですが...ノードでタグを使用することは非常に古いことです。 LISPのような動的に型付けされた言語がどのように実装されたかについて考えられますか?すべてのセルには、その値とタイプを示すタグが必要です。何かが必要な場合は、タグを調べてそれに応じて行動する必要があります。 Haskellの場合、評価状態は型よりも重要であり、Haskellは静的に型付けされます。

STGマシンでは、タグは使用されません。タグは、おそらくOO言語のインスピレーションによって、関数ポインターのセットによって置き換えられました。計算されていないノードの値が必要な場合、関数はそれを計算します。すでに計算されているので、関数はそれを返します。これにより、クライアントコードをこれ以上複雑にすることなく、この関数で実行できることについて多くの創造性が得られます。

この「タグレス」の部分は、SPJによる「ストックハードウェアでの関数型言語の実装」の記事で説明されています。

この「タグのない」ことにも反対があります。基本的に、これには関数ポインターが含まれます。これは、コンピューターアーキテクチャーの用語では間接的なジャンプです。また、間接ジャンプは分岐予測の障害であり、したがって一般的にパイプライン化の障害になります。アーキテクチャは、ジャンプ引数にデータ依存関係があると見なしてパイプラインを停止するか、アーキテクチャが宛先を認識していないと見なしてパイプラインを停止するためです。

16
migle

Migleによる答えは、STGMのスピンレスとタグレスが何を意味するかということです。今日、2つの機能の名前を理解しようとする価値はありません。名前は、Gマシン、スパインレスGマシン、およびスパインレスとタグレスGマシンのグラフ還元テクノロジの歴史に由来するためです。

Gマシンは、スパインとタグの両方を使用します。スパインは、関数適用のルートノードから関数のノードまでのエッジのリストです。たとえば、「f e1 e2 ... en」の関数適用は次のように表されます。

root = AP left_n en
left_n = AP left_n-1 en-1 ...
left_2 = AP left_1 e1
left_1 = FUN f

gマシンでは、スパインはleft_n-> left_n-1-> ...-> left_2-> left_1で構成されるエッジのリストです。文字通り、関数適用の背骨です!

同じ機能アプリケーションには、タグAPとFUNがあります。

Spineless G-machineと呼ばれる次の高度なG-machineでは、最初のスロットがfを指し、2番目のスロットがe1、...を指し、そしてn +1番目のスロットはenを指します。この表現では、スパインは必要ありません。ただし、ブロックはスロット数などを指定する特別なタグを開始します。

Spineless Tagless G-machineと呼ばれる最も高度なG-machineでは、このようなタグは関数ポインタに置き換えられます。関数適用を評価することは、関数ポインタによってコードにジャンプすることです。

Simone Peyton JonesのSTGMの論文が、ある抽象的なレベルで編集/評価のルールを示していないことがわかったのは残念です。そのため、STGMの本質を理解しにくいのは当然のことです。

3
user3509406

機能的なPLの実装に関するSPJの本を読みたいと思います。

3
solrize