イェンセンの装置は、名前による呼び出しを利用するコンピュータプログラミング技術である。これはデンマークのコンピュータ科学者ヨーン・イェンセンによって考案され、彼はRegnecentralenでピーター・ナウルと共に働いていた。彼らはALGOL 60の最も初期の正しい実装の 1 つであるGIER ALGOLコンパイラーに取り組んだ。ALGOL 60 は名前による呼び出しを使用していた。[1] [2] [3]チューリング賞のスピーチの中で、ナウルはイェンセンとの GIER ALGOL での仕事について言及している。
説明
Jensen のデバイスは、名前による呼び出しと副作用を利用します。名前による呼び出しは、引数が実際にプロシージャで使用されるまでその評価を遅らせる引数渡し規則であり、プロシージャのコピー規則の結果です。ALGOL は名前による呼び出しを導入しました。
ジェンセンの手法の典型的な例は、級数の合計を計算する手順である。[ 4] [5] [6]
実数プロシージャSum(k, l, u, ak)
値l, u;
整数k, l, u;
実数ak;
コメントk と ak は名前で渡されます。
開始
実数s;
0 の場合
k := lステップ1でuが実行するまで
s := s + ak;
合計 := s
終わり;
プロシージャでは、インデックス変数kと合計項はak名前で渡されます。名前による呼び出しにより、プロシージャはループの実行中にインデックス変数の値を変更できますfor。また、名前による呼び出しにより、akループの各反復中に引数が再評価されます。通常、akは変化する (副作用のある) に依存しますk。
たとえば、実数配列の最初の 100 項の合計を計算するコードは次V[]のようになります。
合計(i, 1, 100, V[i])。
の実行中Sum、実際の引数はループiの各ステップで増加しfor、 の各プロシージャの評価ではakの現在の値を使用してi、連続する配列要素にアクセスしますV[i]。
ジェンセンの手法は一般的です。二重加算は次のように実行できます。
合計(i, l, m, 合計(j, l, n, A[i,j]))
関数Sumは、適切な式を使用するだけで任意の関数に使用できます。整数の和が必要な場合は、式は となりSum(i,1,100,i);、整数の平方和が必要な場合は となりSum(i,1,100,i*i);、以下同様です。[7]式の数値積分を開始するには、 と非常によく似た方法でわずかなバリエーションが適していますSum。
の評価は、本質的には環境を持つサブルーチンであるサンクakを使用して実装されます。サンクは引数のないクロージャです。プロシージャが仮引数の値を必要とするたびに、サンクが呼び出されます。サンクは、呼び出しコードのスコープ内で実際の引数を評価します (プロシージャのスコープ内ではありません)。
この名前渡し機能がない場合、コンピュータ言語のプロトコルに従って渡される式を具体化する関数を定義するか、または各使用法に対して目的の式を選択するための何らかの取り決めとともに概要関数を作成する必要があります。
GPS
もう一つの例は、DE KnuthとJN MernerのALGOL 60 confidentialで説明されているGPS(General Problem Solver)です。[8]
実 手順GPS(I, N, Z, V);実I, N, Z, V;
begin for I := 1 step 1 until N do Z := V; GPS := 1 end ;
以下は、GPS を使用して m 番目の素数を見つける単一のステートメントです。
I := GPS(I, if I=0 then -1.0 else I, P, if I=1 then 1.0 else
if GPS(A, I, Z, if A=1 then 1.0 else
if entier(A)×(entier(I)÷entier(A))=entier(I) ∧ A<I
then 0.0 else Z) = Z then
( if P<m then P+1 else I×GPS(A, 1.0, I, -1.0)) else P)
(注: 元の論文では、末尾近くの式は となっていますが、これは ALGOL 60 のforGPS(A, 1.0. I, 0.0)文のセマンティクスの仕様における特殊なケースによるものです。)
批判
ジェンセンの手法は名前による呼び出しに依存しているが、名前による呼び出しは微妙で、いくつかの問題がある。その結果、名前による呼び出しはほとんどの言語では利用できない。クヌースは、ALGOL 60 ではincrement(n)引数を 1 つ増やす手順を表現できないとコメントしている。呼び出しがアクセスごとに変化する関数であるincrement(A[i])場合、期待される動作は実行されない。 [9]クヌースは、「この目的のために手順のみに依存するのではなく、言語を拡張するために「マクロ」定義機能を使用すると、より満足のいく実行プログラムが得られる」と述べている。
i
他の人は、引数を交換する名前による呼び出し手順には微妙な問題がある可能性があると指摘しています。[10]明らかな交換手順は次のとおりです。
手順swap(a, b)
整数a, b;
開始
整数temp;
温度:=a;
a := b;
b := 温度;
終わり;
この手順は多くの引数に対しては正しく動作しますが、 の呼び出しにはswap(i,A[i])問題があります。コピー ルールを使用すると、次の割り当てが行われます。
温度:= i; i := A[i]; A[i] := 温度;
問題は、2 番目の割り当てによって が変更されるiため、A[i]3 番目の割り当ての が開始時と同じ配列要素にならない可能性があることです。一方、プロシージャが逆の方法でコード化された場合 ( bがaではなくtempに保存される)、 として呼び出されない限り、目的のアクションが実行されます。(より安全なのは です。)
swap(A[i],i)swap()temp1 := a; temp2 := b; a := temp2; b := temp1;
参照
参考文献
- ^ Naur, Peter (2005). Peter Naur Lecture Video. ACM Awards . デンマーク: Association for Computing Machinery . 2020年9月11日閲覧。
- ^ David (2006年3月1日). 「ソフトウェアのパイオニア、ピーター・ナウアがACMのチューリング賞を受賞」ACM公共政策. Association for Computing Machinery . 2020年9月11日閲覧。
- ^ 「ACM: フェロー: ピーター・ナウア、コペンハーゲン大学名誉教授、引用」。2005年。2008年2月12日時点のオリジナルよりアーカイブ。 2020年9月21日閲覧。2008-02-12にWayback Machineにアーカイブされました
- ^ MacLennan, Bruce J. (1987).プログラミング言語の原則: 設計、評価、実装(第 2 版). Holt, Rinehart & Winston. pp. 141–2. ISBN 0-03-005163-0。
- ^ Dijkstra, EW (1961年11月). 「ALGOL 60の擁護(編集者への手紙)」. Communications of the ACM . 4 (11): 502–503. doi : 10.1145/366813.366844 . S2CID 34185299.
- ^ Knuth, DE (1967 年 10 月). 「ALGOL 60 に残る問題点」. Communications of the ACM . 10 (10): 611–617. doi : 10.1145/363717.363743 . S2CID 10070608.
- ^ は 用語の引数を
Sum必要とするため、型変換が想定されます。real - ^ クヌース、ドナルド E.ジャック・N・マーナー(1961年6月)。 「ALGOL 60 機密」。共通。 ACM。4 (6): 268–272。土井:10.1145/366573.366599。S2CID 22215746。
- ^ Knuth 1967、p. 613。たとえば、は 2 倍
increment(A[increment(j)])に増加しますj。 - ^ マクレナン 1987
外部リンク
- ALGOL スタイルのブロック構造と名前による呼び出しのための標準のストアレス セマンティクス
