😎

構造化プログラミングを調べた

2024/01/28に公開

構造化プログラミングを調べた

プログラミングパラダイム っていろいろあるんですが、命令型プログラミングオブジェクト指向プログラミングなどは定義が比較的分かりやすいと思います。(正しい定義を説明できるかと言われても無理ですが、雰囲気はわかりやすい)

しかし、構造化プログラミングは (少なくとも私は) よくわかってませんので、調べてみました。

主な情報ソースは Wikipedia ですが、知人とあーでもないこーでもないとしながら一定の結論が出ましたのでメモがてら書いてみます。(合ってるとは限らない)

手続き型プログラミング

その前に、手続き型プログラミングについて少しだけ。手続き型プログラミングは構造化プログラミングの一つ前と誤解しておりました。

Wikipedia では導入でこのように解説されています。

手続き型プログラミング(てつづきがたプログラミング、英: Procedural programming)は、手続きの定義と呼び出しをプログラム全体を組み立てる土台にしたプログラミングパラダイムである。手続きは言語によってサブルーチン、関数、メソッドとも呼ばれている。

私の今までの経験では、プロシージャーを定義できないプログラム言語の経験はありません。アプリケーション組み込みや簡単なゲームエンジン用のミニマクロ言語やミニスクリプト言語ではそういうのがあったように思います。

余談ですけど、私が最初に触った PC-8001 には N-BASIC が搭載されていました。当時はサブルーチンがないと思ってたのですが、実際にはあったようです。(ただし、ローカル変数はありませんし戻り値もありません) なので、そのころ私が書いていたプログラムは非手続き型になるようです。

構造化プログラミング

構造化プログラミングの初出は 1969 年のダイクストラ氏のようです。それに対して構造化定理がミルズ氏によって 1970 年前半に定義されたようです。ダイクストラ氏の 1968 年の「goto 文は有害」も併せてごっちゃになって構造化プログラミングが分かりにくくなっているようです。

構造化定理による構造化プログラミング

構造化定理は 1970 年前半にミルズ氏が定義しているようですが、実際にはもっと古くから論文としてあったようです。

構造化定理は順次・選択 (分岐)・繰り返しの三つの組み合わせで入出力の処理が書けるとかそんなのです。goto 文が不要になるとかそんな話です。しかし、これらの三つがないプログラム言語って 1960 年代後半にあったのかな? と疑問に思います。

そこでちょっと思い出したのが PC-8001 の N-BASIC です。分岐は GOTO 文を併用していました。(N-BASIC に限らず、当時のマイコンの BASIC は大体同様です)

100 IF A=1 THEN 110 ELSE 200
110 ' 真の時の処理
120 ' 真の時の処理
130 ' 真の時の処理
140 GOTO 300
200 ' 偽の時の処理
210 ' 偽の時の処理
300 ' 続きの処理

当時の BASIC はブロックという概念がなく、分岐は行番号 (ラベルが使える BASIC もあった) へのジャンプで、処理の終わりに GOTO で次の処理へジャンプさせる必要がありました。当時はプログラムが短かったのでこれでも気にしたことはなかったのですが、今考えるとよくやってたなあと思います。

この文脈での構造化プログラミング言語には、選択と繰り返しでのブロックのサポートが必要なのではないかと思われます。

ダイクストラ氏の構造化プログラミング

初期のコンピュータープログラミングは職人芸だったようです。コンピューターの能力も低い上に、今のようにアーキテクチャが共通になっていないので、同じメーカーの上位機種を導入したらプログラムは書き直しとかそういった状態だったようです。

ところが 1960 年代には大規模な開発が増えてきます。有名どころは IBM のメインフレーム SYSTEM/360 用の OS、OS/360 の開発や NASA のアポロ計画などがそうです。このため、職人芸のような個人芸の延長ではソフトウェア開発は続けられなくなると考えられていました。(ソフトウェア危機
)

ダイクストラ氏はこれを乗り越えるためにはプログラムが正しいかどうかを証明する方法を確立する必要があり、テストだけでは不十分で、プログラミングそのものにもそれを導入する必要があると考えていたようです。そのための構造化されたプログラミング手法です。

一番中核となったのが抽象データ構造のようです。抽象データ構造とはなんぞや? って話ですが、Wikipedia には次のように書かれています。

この概念はプログラミング言語の理論で用いられる抽象データ型の概念に非常に近い。多くの抽象データ構造や抽象データ型の名前は具体的なデータ構造の名前と一致する。

つまりは、動くようにプログラムを書くのではなく、トップダウン式で抽象化された構造の組み合わせで作っていくスタイルということになるようです。

多分こんな感じです。(ショッピングカートの例です)

var cart = cartDataSource.Load(sessionId);
var product = itemDataSource.Get(productCode);

cart.AddProduct(product, 1);

cartDataSource.Save(cart);

この例では、カートがどのようにデータベースに永続化されているかや、カートに商品を追加するときの処理は抽象化されています。(一般的に、同じ商品がカートにあれば数を増やしますが、そのようなことは Cart 抽象データ型ないしはさらにその下の抽象データ型に書かれています)

余談になりますが、だいぶオブジェクト指向プログラミング (C++ 系の) に近いなあと感じました。Wikipedia にもそのような記述があります。

ダイクストラの構造化プログラミングは、制御構文と構造化定理と構造化設計の影に隠れながらも、Simula67をモデルにしたオブジェクト指向プログラミング発展の歴史に組み込まれて受け継がれていったと言える。1983年にC++を開発したビャーネ・ストロヴストルップは「What Is Object-Oriented Programming?[32]」において、オブジェクト指向を抽象データ構造と階層的プログラム構造の発展形として解説し、同時にSimula67の言語仕様を紹介している。

最後に

余談ですけど、構造化設計や構造化分析といったものもあり、これらを利用したものを構造化プログラミングと呼ぶこともあるようです。(ダイクストラの構造化プログラミングに近いような気がします)

個人的にはダイクストラ氏の提唱した構造化プログラミングが一番好みだったので、構造化プログラミングとはダイクストラ氏の提唱したものとしたいと思います。

Discussion