構造化プログラミング
構造化プログラミング（こうぞうかプログラミング｜）は、コンピュータ・プログラムに構造を導入して記述をより簡素明快にし、ソフトウェアの品質の向上と開発の効率化を目指したコンピュータ・プログラミング技術である。
今日の「構造化プログラミング」は複数の誤解を招く言葉となっており、本来の定義とソフトウェア技術者を含む世間の用法の間に差異が生じている。この様な事情から構造化プログラミングには以下の3つの解釈が存在している。今日の構造化プログラミングに対する一般的な認識は、(2)と(3)が示す「順次、選択、反復といった制御フローをブロック単位で表現し、それらを直列または入れ子状に配置する事でプログラムの構造化を実現する」という事になっている。
しかし、(1)のダイクストラが提唱した理論が本来の意味での構造化プログラミングであり、本稿では(1)について説明する。(2)と(3)については「構造化定理」が該当記事となる。
ダイクストラは1969年のワーキングペーパーで構造化プログラミングについて以下のように語っている。以上のように構造化定理とはあまり関係のないことであるが、現在でも構造化プログラミングと構造化定理は混同されている。
コンピュータが実用化され、その有用性が認められるようになるにつれ、その上で動作するプログラムは次第に大規模なものとなっていった。ソフトウェアの低品質、納期遅れ、予算超過が頻発し、大規模なプログラムを正当に動作するように記述することの困難さが認識されるようになった。遡れば、コンピュータ・プログラムのデバッグという仕事の大変さについて1949年に感じた、ということを自伝に残しているウィルクスが、その後に、アラン・チューリングが「大規模ルーチンの検証」といったことを話していた、と書いている。
1960年代ではプログラムはフローチャートによる設計が広く採用されており、goto文も広く使われていた。その一方でgoto文の多用はプログラムの質を下げるという性質や、多くのプログラムはgotoを使わずに記述できるという性質が経験則として知られていた。例えば1959年のハインツ・ツェマネクによるgoto文への疑問。1960年から始まるD. V. Schorreによるインデントで制御の流れを表すアウトライン形式のプログラム記述、1963年のPeter Naurのgo to文に隠れたfor文の指摘、その翌年のGeorge Forsytheによるアルゴリズムからのgo to文除去、1965年のダイクストラや1966年のPeter Landinによるgo to文なしプログラミングの実験に関する発表が挙げられる。
そして1966年コラド・ベームとジュゼッペ・ヤコピーニによって、任意のフローチャートは基本フローチャートの組み合わせによる等価なフローチャートに変換できるという定理が示された。この定理は後に、IBMの研究員らによって構造化定理(Structure Theorem)として再定義された。なお前述のように、これを構造化プログラミングと結びつける論者は大変多いが誤解である。
1968年にダイクストラは“Go To Statement Considered Harmful”という記事を発表し、大きな反響を呼んだ。この騒ぎがきっかけで構造化プログラミングを知った者が多いことを示して、クヌースは「go to文を用いた構造化プログラミング」の中で「go to 文除去の話の二番目の場面は，多くの人たちが第一幕だと思っている事実である．」とこの騒動を指して評している。1980年代にマイコンが普及した際に、そのBASICにおいて（由来などの詳細は全く曖昧なまま）「GOTO命令を使わないのが『構造化プログラミング』」などと言われたりしたなど、騒動の影響は後年まで残った。
1968年、NATO主催のソフトウェア工学会議でソフトウェア危機が共通認識となったとき、ダイクストラは時が来たと考えた。当時、ダイクストラを含むソフトウェア危機の存在に気づいていた人々は、プログラミング活動に対する変化の到来を予測していた。しかしこの転換期が訪れるまで、世間一般はそれを受け入れる準備ができていなかった。
翌1969年、再び開催されたNATOのソフトウェア工学会議において、ダイクストラは「構造化プログラミング(Structured Programming)」という語を提唱した。ダイクストラはこの提唱において goto 文に一言触れただけで、プログラムサイズが大きくなったとしても正しさを証明できる良く構造化されたプログラム(well-structured programs)、大きなプログラムの理解を助ける段階的な抽象化(step-wise abstraction)、抽象データとその操作の抽象文の共同詳細化(joint refinement)、そして真珠のネックレスに例えたプログラムの階層化について述べた。
ダイクストラは、構造化プログラミングという言葉を作ったとき2つの失敗をしたと述べた。商標登録しなかったことと定義しなかったことである。そのため、構造化プログラミングは標語（スローガン）となってしまい、IBMのプログラミング規範をまとめたIPT(Improved Programming Technologies)によって当時のプログラマに広く流布した。構造化プログラミングはIBMによって発明されたと信じる者も数多く存在した。しかしIBMの構造化プログラミングは、ダイクストラのそれとは異なるものであった。産業界や米国ではダイクストラの原則はむしろ不人気でさえあった。
1980年代以降、ソフトウェア工学の分野はプログラミング言語や方法論から組織やプロジェクトの管理手法へと軸足を移していた。1987年の第9回ソフトウェア工学国際会議(ICSE)において、IBMの研究員は会場にチューリング賞受賞者がいないことを確かめると「ダイクストラやホーア達はどこへ行ってしまったのか。我々はもう彼らから学ぶものがないのか。」とその現状を批判した。
しかし、木村泉の見解が当たっていたとするならば、「ソフトウェア工学」をそういったものにしていった張本人こそが、その発言をしたハーラン・ミルズであるということになる。ミルズは「構造化定理」という言葉を作り、IBMの研究員の立場を利用して、構造化プログラミングと構造化定理を混同させたと言える。
後年、ダイクストラは自身が作った構造化プログラミングという言葉に不快感を示し、避けるようになった。この言葉を名付けたとき、かれはプログラミングが手工芸から科学へ発展することを予測していた。しかし構造化プログラミングという言葉は実利を求めるために使われるようになった。次のような逸話がある。ヨードンの会社に依頼の電話がかかってきた。部下全員に構造化プログラミングなどの構造化技法を1日で叩きこんで欲しいという内容である。それが終わったら開発期間を半分にするという。なぜなら「構造化技法は生産性を2倍にしますから」というものであった。かくして構造化プログラミングは、ダイクストラの期待とは異なった形で世に広まっていくことになる。
歴史的経緯から、構造化プログラミングはIBMの（Harlan Mills）の提案に由来するgoto-lessプログラミングとして一部分を切り取られた形で広く知られている。むしろそれこそが「構造化プログラミング」（あるいは「goto有害論」）であると信じて書かれている文献も多い。
岩波情報科学『算法表現論』p. 58 から言葉を借りるならばその実態は「プログラマー（職業としてではなく職種としての）に codice_1 や codice_2 や codice_3 だけを使用させ，codice_4 の使用を禁止すれば，ダメな連中でも少しはましなプログラムを書いてくるだろう」というもので、「広く影響を及ぼしたが，内容は Dijkstra（ダイクストラ）流とはほとんど無関係」である。
まず、以下のことに関してダイクストラが主張した、というのは事実である。
ダイクストラは“Go To Statement Considered Harmful”および“Structured Programming”において、好ましい構造として手続き呼び出しの他に、順次・反復・分岐の3つを挙げた。ヴィルトはこれらを構造化文(structured statement)と呼んだ 。goto文を避けて構造化文を用いるようプログラマーに教えることが、構造化プログラミングの伝統的な知恵である。また、“Structured Programming”や“Structured Programming with go to Statements”においては抽象データ構造の重要性も主張されている。加えて1972年、オルヨハン・ダール、ダイクストラ、ホーアによる書籍“Structured Programming”においてはSimulaによるクラスを使ったプログラムの階層化の考え方も紹介されている。これらの考え方は後の本格的なオブジェクト指向へと発展する。例えばC++の開発者であるビャーネ・ストロヴストルップはオブジェクト指向について解説した記事“What Is Object-Oriented Programming?”において抽象データ構造の発展としてオブジェクト指向を解説し、そのための手段としてSimulaの機能を紹介している。
以上の事実について後年の多くの論者が、構造化定理（Structure theorem）と結びつけ、構造化定理の示す所では、gotoを使わなくてもこの3種類の制御構造を組み合わせることでプログラムは書ける、というのだから、goto文を排除してプログラムを書くことが構造化プログラミングである、と、その名前の類似（日本語でも英語でも）や、「goto有害説」という表現のインパクトから、ほとんどの場合は誤解されている、と言っていいほどに誤解されている。
実際のところは、構造化定理はフローチャートやそれによって表現されるプログラム・関数・チューリングマシンなどの理論的側面に注目している。これは任意の論理回路がNAND素子の組み合わせによって表現できるとか、λ式がSおよびKという名の2つのコンビネータによって表現できるとかいった研究に近い。回路設計者が直接NANDを組み合わせて電子回路を設計しないのと同じように、構造化定理は良いプログラムの作成を(少なくとも直接的には)意図していない。
クヌースは文献において、良い構造が重要なのであり、良い構造はFORTRAN, COBOL, アセンブリ言語でも記述できるとした。一方で、（構造化定理により）機械的にgotoを除去する変換を掛けたプログラムとは実際にどんなものになるのか、変換法の一例を示し、1つのループがプログラム全体の振る舞いを含んでしまうため、抽象化レベルという点では無意味であるとした。クヌースがそこで実際に示した、「機械的にgotoを除去」したコードと同様のものが 構造化定理#単一の while ループ、この定理の民間伝承バージョン に示されているが、見ればわかるようにgotoを使っていないというだけで、手続きのわかりやすい表現には全くなっていない。曰く「これですべての goto 文を除去できたわけであるが，実際にはすべての構造を失ってしまっている．」というわけである。
ダイクストラも“Go To Statement Considered Harmful”においては最後の段落で、goto文の(論理的な)余分さを証明したようだと軽く触れたのみであり、作られるフローチャートは元のものより正しさの証明が簡単になるとは思えないためジャンプを含まないフローチャートの機械的な作成は推奨しないとした。
コンピュータは与えたプログラムに応じてそれを計算し結果を出力するという装置であるが、プログラムに誤りがあると、当初の意図した命題（仕様）を肯定しないものとなる。
プログラマは、正しいプログラムを作り出すばかりでなく、納得のいくやり方で正しさを証明することも仕事の一つであるという立場を取っていたダイクストラは、プログラムの正しさの納得のいく証明を遂行するための手法を導入した。ただし、その検証を実行するためには対象となるプログラムは「うまく構造化」されていなくてはならず、その「うまく構造化」されたプログラムを開発する手法が構造化プログラミングである。
構造化プログラミングの支持者らは、プログラムの正しさの重要性と証明の方法や表明(assertion)の使い方について熱心に説いた。
ダイクストラは、プログラミングと同時にプログラムの証明を（わずかに証明を先行して）進めることを推奨している。そのようなアプローチでプログラムの正当性の問題にあたれば、複雑な問題であっても知的管理が可能であると述べた。
また、プログラムの証明に対する反論も存在する。マイケル・ジャクソンは、個々のプログラムに証明を付けることは現実的には難しいだろうと述べている。