段階的な機能とは(概念的に)


24

最近のCACMの記事[1]で、著者は段階的な機能の実装を提示しています。彼らはそれがよく知られているかのようにこの用語を使用し、どの参考文献も明らかな紹介のようには見えません。

彼らは簡単な説明をします(強調鉱山と参照番号が変更されました;オリジナルでは22です)

プログラム生成のコンテキストでは、Taha and Sheard [2] によって確立されたマルチステージプログラミング(MSP、略してステージング)により、プログラマーはプログラム式の評価を後のステージに明示的に遅らせることができます(したがって、式のステージング)。現在のステージは、次のステージのプログラムを構成(および場合によっては実行)するコードジェネレーターとして効果的に機能します。

ただし、Taha and Sheardは次のように書いています(強調強調):

マルチステージプログラムは、コードの生成、コンパイル、実行をすべて含むプロセスであり、すべて同じプロセス内にあります。多段階言語は多段階プログラムを表現します。ステージング、したがってマルチステージプログラミングは、実行時の解釈オーバーヘッドを払わない汎用ソリューションの必要性に対処します。

彼らはさらに、ステージングが効果的であることを示す古い作品へのいくつかの参照に進み、それは概念がさらに古いことを示唆しています。彼らは用語自体の参照を与えません。

これらの記述は、矛盾していないにしても、直交しているように見えます。RompfとOderskyが書いたものは、TahaとSheardが提案したものの応用かもしれませんが、それは同じことに関する別の視点かもしれません。彼らは重要な点は、実行時にプログラムが自分自身の一部を(再)作成することであることに同意しているようですが、それが必要な能力であるか、十分な能力であるかはわかりません。

それでは、このコンテキストでのステージングの解釈は、それぞれステージングとは何ですか?この用語はどこから来たのですか?


  1. 軽量モジュラーステージング: T. RompfおよびM. Oderskyによるランタイムコード生成およびコンパイル済みDSLへの実用的なアプローチ(2012)
  2. W. TahaおよびT. Sheardによる明示的な注釈付きのMetaMLおよびマルチステージプログラミング(2000)

2つの声明の間に矛盾はありますか?私には、彼らは同じことを話しているように見えますが、強調は異なります。
ジル「SO-悪であるのをやめる」

@Gilles何かの評価を遅らせるために、実行時のコード生成/コンパイルは必要ありません(継続可能モジュールを参照)。それは別の強調点である可能性が非常に高いかもしれません(質問でそのオプションを認めます)が、私は本当に言うことができません。
ラファエル

あなたはジュリアは、言語の実装をプログラミングし、上のドキュメントをメタプログラミングチェックアウトすることができ@generated function、S:julia.readthedocs.org/en/latest/manual/metaprogramming/...
SalchiPapa

回答:


21

私の知る限りでは、段階的計算という用語この論文で Bill Scherlisによって最初に使用されました。それ以前は、「部分評価」という用語はほぼ同じ概念に使用されていましたが、段階的計算の考え方は微妙に異なります。両方のアイデアは、KleeneのSmn定理に関連しています。

2つの引数の関数あり、1つの引数、たとえばmを知っている場合、最初の引数の知識を使用して、関数の計算の一部をすぐに実行できます。残っているのは、計算が2番目の未知の引数のみに依存する関数ϕ mn です。ϕmnmϕmn

部分評価の考え方は、特殊な関数自動的に計算することです。元の関数のコード所与φ、部分的な評価は、コードのビットに依存するかを決定するために静的解析を行い、M、どのビットに依存するn個の機能に、及び変換をφ '、与えられたM、構築φ M。次に、2番目の引数nをこの特殊な関数に渡すことができます。ϕmn ϕmnϕmϕmn

段階的な計算の考え方は、関数を考えることである最初。複数のステージで機能するため、「ステージング」機能と呼ばれます。最初の引数mを与えると、特殊な関数ϕ mのコードを作成します。これが「最初の段階」です。2番目の段階では、2番目の引数がϕ mに提供され、残りのジョブを実行します。ϕmϕmϕm

だから、部分評価の仕事は、通常の関数のコード変換することである上演し、関数にφ "。シェリスは、この変換は、以前の部分評価方法よりも一般的なメカニズムで実行できると考えていました。「段階的計算」の主題は、次のような問題を扱うようになりました。ϕϕ

  • 段階的な機能の定義方法
  • 段階的な機能を定義するには、どのプログラミング言語と型システムを使用する必要がありますか?
  • そのような言語のセマンティクスは何ですか?
  • 段階的な機能の一貫性と正確性をどのように確保しますか?
  • 段階的機能を自動または半自動で構築するのに役立つテクニックは何ですか?
  • そのような手法の正確性をどのように証明しますか?

段階的な計算は、実際には非常に重要です。実際、すべてのコンパイラは事実上段階的な計算です。ソースプログラムが与えられると、翻訳され最適化されたターゲットプログラムを構築し、実際の入力を取得して結果を計算できます。ステージングされた計算プログラムを実際に作成するのは困難です。なぜなら、複数のステージをジャグリングして、適切なタイミングで適切な処理が行われるようにする必要があるからです。コンパイラを書いた人は皆、このような問題に苦しんでいます。また、機械語プログラム(コンパイラー)、SQLクエリ(データベース操作)、HTML / Server Pages / Javascriptコード(Webアプリケーション)など、他のプログラムを作成するプログラムを作成することは困難です。


ϕϕ

つまり、部分評価とは、多段階プログラミングの抽象化です。つまり、部分評価は多段階プログラミングを意味するのではなく、多段階プログラミングは部分評価を意味します。関数型言語でのカリー化は、実行時に複数のステージとコード生成を必ずしも必要としないため、部分評価は1つまたは複数のステージで実行できます。
denis631

1
ではない正確に。部分評価者は、通常のプログラムを2段階のプログラムにコンパイルし、最初の段階を実行します。段階的プログラミングでは、マルチステージプログラムを自分で作成します。
ウダイレディ

9

他の答えは技術的には正しいのですが、コンピューター科学者が段階的な機能に興味を持っている理由を正しく理解しているとは思いません。

段階的な機能を作成することにより、プログラムを生成するプログラムを定義します。現代の実用的な言語理論の大きな目標の1つは、潜在的な再利用を最大限にすることです。有用な関数やオブジェクトだけでなく、高次のアーキテクチャ構築を提供することでプログラマを支援するライブラリを作成できるようにしたいと考えています。

すべての定型コードを取り除くことができれば素晴らしいと思います。仕様言語を最小限に抑えることができるはずです。たとえば、特定のスレッド設計で他のディスパッチャと通信するイベント駆動ディスパッチャが必要な場合は、それをコンパクトに指定できる必要があり、すべてのIOリスナーとキューオブジェクトとスレッド接続をその仕様から構築できる必要があります。

ドメイン言語は、私たちが探しているコンパクトな表現になりがちです。人々がしばらくドメインで作業するとき、使用する言語は情報のほとんどの重複を取り除き、無駄のない仕様になる傾向があります。したがって、このステージングの理論は、ドメイン言語から実行言語への翻訳システムになる傾向があります。

コンパイラは技術的にはステージャーですが、目標を逃しています。最新のステージングの目標は、プログラムを構築するプログラムを構築して、可能な限り再利用を最大限にし、プログラム構築を自動化することです。プログラムの1日の機能要件がプログラムであれば、それは素晴らしいことです。

CzarneckiとEiseneckerによる「Generative Programming」(ISBN-13:978-0201309775)を参照してください。


@Raphael:ドメインと再利用の基本を含む第3章です。あなたが言及した最適化を見てください。FFTは、実行速度を上げるためのステージングでは行われません。プログラマーが毎回値の表を手作業で計算し、それらをプログラムにコピーし、大きなリストを作成する必要がないようになっています。行われる作業を最小限に抑え、基本的な手順を再利用することです。ループの展開と同じです。手作業で行うと情報が繰り返され、再利用できなくなります。
ex0du5

このDSLの観点は、ステージングを1レベル(プログラム内の1つのDSLコンパイラー)に制限しているようです。
ラファエル

1
@Raphael:それは本当にあなたの視点に依存します。明らかに、この概念は、単にソース->実行可能な翻訳として見た場合、計算能力を追加しません。DS言語用のコンパイラを作成するだけで完了します。その強みはどこから来るのかということです。将来プロジェクトで使用および拡張されるライブラリを構築する場合、ライブラリの境界内に自然な段階が現れます。オブジェクト仕様を完全なシリアル化のためのソースに変換するライブラリがあり、その後、いくつかのディスパッチ仕様に基づいてトランスポート層を構築する別のライブラリがあります...
ex0du5

1
@Raphael:ステージングは​​、複数のステージでより自然に行われます。あるコードの要件が時間とともに大きく変化し、他のコードがより安定している場合、「シアリングレイヤー」により、ステージングをより安定したインターフェイスを持つレイヤーに分離することが適切な場合があります。その後、変更によりシステムへの影響を減らし、オープンクローズド原則のステージング形式を尊重できます。これらは数学的必要性を持たない実際的な懸念ですが、それはすべて実用性に基づいています。単一のコンパイラ言語は必要ありません。進化を可能にしたいと考えています。
ex0du5

5

答えは、問題の記事の技術的観点の部分にあります[1]。検討中の問題は、一般的なコードと特定のコードの間の緊張の領域です。

プログラムは、汎用または専用のいずれかに作成できます。汎用コードには、さまざまな状況で使用できるという利点がありますが、特殊用途のコードは、実行環境の固有の特性を利用して再利用性を犠牲にして効率を高める方法で記述できます。

もちろん、一般的なコード特定の実装を達成するというこの緊張を解決したいと思います。

私たちは質問をすることができます:汎用であるようにコードを書くことは可能ですが、実行中に手元の状況に自動的に特化させることができますか?

これにより、特定の状況に対応するために、実行時に(一般的な)プログラムを(再)作成するというアイデアが生まれました。

その結果、重要な研究の方向性は、プログラマが汎用コードを記述し、実行時に正しく効率的に高性能の特殊コードに変換できるようにする言語およびコンパイラテクノロジの検索に関係しています。

JavaのJITが良い例だと思います。特定のアイデアの1つはマルチステージプログラミングで、リーは次のように説明しています。

この一連の研究では、核となるアイデアの1つがステージングの概念です。プログラムの実行が一連の段階で進行し、それぞれが後の段階で使用される値を計算することを想像します。私たちが求めているのは、これらの段階がどういうわけか明らかになるようにプログラムコードを書くことです。これが達成されれば、後の段階のコードを、前の段階の計算の結果に対して最適化するコードジェネレーターにコンパイルするように手配できます。

つまり、「ステージング」は、前のフェーズの結果を知ることで簡略化できる計算/実行のフェーズを識別する適切な関数/コードを調べる方法です。質問の最初の引用のように計算を「遅らせる」ことは、ステージを適切に分離するために必要な副作用かもしれませんが、それはポイントではありません。

RompfとOderskyは、有益な例として高速フーリエ変換について言及しています。


  1. キツネとハリネズミ:ピーターリーによる技術的展望(2012)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.