プログラマがどうすべきかについての意見は差し控えたい。というのは、この件に関してはKnuthの論文があり、この論文は、それを紹介するエントリーで軽々しく自分の意見を併記することを許さないほどすばらしいからである
1974年に書かれた論文「goto文を用いた構造的プログラミング」のアブストラクトは次の通り
異なった例題をいくつも考察した結果、信頼性があり、整構造をした、効率よいプログラムを書くという問題に、新しい光を当てることができた。この研究は、主に次の2種類の論点から論じている。(a) goto文を用いずに明快で効率よいプログラム群を書くことが可能になるような、反復構文およびエラー抜け出し構文の改善について。(b) 読みやすく正しいけれども効率のよくないプログラムから初めて、必要なら効率がよく正しいけれども必ずしも読みやすくはないプログラムに、系統だてて変換するプログラム設計手法について。この議論から、goto文を用いるべきか否かという対立する論点を表に出す。どちらの側にも、いくつかの利点があることがわかる。最後に、構造的プログラミングの本来の性格を定義し、将来の研究に実りある方向付けを示すための試みをする。
この論文は、Knuth『文芸的プログラミング』に収録されている
アブストラクトにあるとおり、この論文では複数の例題が扱われているが、最初の例題を紹介しよう
異なる値が入っている表A[1]…A[m]を探索して、変数xの値が存在するか否かを調べたいものとしよう。もしxが存在しない場合には、Aにその項目を追加するものとする。さらに、もう一つの配列Bがあって、B[i]の値はA[i]の値を探した回数に等しいものとしよう。
第1の解
for i:=1 step 1 until m do
if A[i]=x then go to found fi;
not found: i:=m+1; m:=i;
A[i]:=x; B[i]:=0;
found: B[i]:=B[i]+1;
この問題は、次のようにgotoなしで書くことができる
第1aの解
i:=1;
while i<=m and A[i]!=x do i:=i+1;
if i>m then m:=i; A[i]:=x; B[i]:=0 fi;
B[i]:=B[i]+1;
解1aはiとmの比較が余分な点(およびときどきm+1の計算が少ないこと)以外は、解1と完全に同じ計算をする。このwhile文の反復を多数回行うと、余分な比較は実行時間では無視できるくらい小さい。
したがって、解1ではgoto文を使わずにすむ。しかし解1aは私の考えではやや読みやすさで劣り、またわずかではあるが実行速度も遅い。goto文を除去して本当に利益があったかどうかは、はっきりしない。
(中略)
この例題は説得力に欠ける。なぜなら、配列の中でxの値を探すプログラムとして、解1は適切なものではないからである。次のようにデータ構造を変えることで、アルゴリズムはずっとよくなる。
第2の解
A[m+1]:=x; i:=1;
while A[i]!=x do i:=i+1;
if i>m then m:=i; B[i]:=1;
else B[i]:=B[i]+1 fi;
典型的なコンピュータ上でのデータや命令のメモリ参照は、解1については6n+10(値が見つからなかった場合はさらに+3)回である。しかし解2のほうは、4n+14(値が見つからなかった場合はさらに+6)回ですむ。さらに添字の上下限検査を省いた典型的な「90%の最適化コンパイラ」を用いたとすれば、実行時間はそれぞれ14n+5および11n+21となる。(本論文の末尾に添えた付録に、この計算のための基本的なルールを説明しておく。)
このように引用するとgotoは要らないのだと思うかもしれないが、ことはそう単純ではなく・・・。まあ、あとは実際に読んでもらうのがいいと思う。『文芸的プログラミング』には、アートについてのもっとも重要な文献の一つ、「芸術としてのプログラミング」(Turing賞受賞講演)も収録されている
No related posts.
