理論形成としてのプログラミング (1985)
(gwern.net)- Peter Naurの「Programming as Theory Building」は、プログラミングをプログラムテキストを生産する活動ではなく、プログラマが問題と解法についての理論を形成する活動として捉える。
- ここでいう「理論」は、単なる抽象的命題や文書化された設計説明ではない。
- 現実世界の問題がどのような意味を持つのかを理解し
- プログラム構造がその現実とどのように対応しているかを説明でき
- なぜそのように設計したのかを正当化し
- 新しい要求が入ったとき、既存構造の中でどのように統合するかを判断できる能力である。
- したがってプログラムの中核知識はコードや文書の中に完全に収まるのではなく、そのプログラムを理解しているプログラマの頭の中にある。
プログラミングと知識
- Naurはプログラミングを、現実世界の活動をコンピュータが実行できる形式的な記号操作に対応づける活動だと見る。
- この観点では、プログラム修正もプログラミングの一部である。
- 現実世界の活動が変われば、プログラムも変わらなければならないからである。
- プログラミングの本質は文書やコードという成果物ではなく、プログラマたちが積み上げていく特定の知識にある。
- 文書は重要だが補助的である。
- 文書は理論を完全には代替できない。
- 文書は理論形成を助ける道具に近い。
事例 1: コンパイラ移管と失敗
- グループAは言語L向けのコンパイラを作った。
- グループBは拡張言語L + M向けのコンパイラを作るために、Aのコンパイラコードと文書、助言を提供された。
- コードと文書は十分に提供されたが、Bはいくつかの設計で既存構造の強みを活かせず、パッチ的な解法を提案した。
- Aはすぐに問題を見抜き、既存構造の中でより単純で自然な解法を示した。
- この事例の核心:
- プログラムテキストと文書だけでは、設計の深い理論は伝わらない。
- 既存設計の「なぜ」と「どう拡張すべきか」は、文書だけでは十分に伝わらない。
- その後、Aの指導を受けていない別のプログラマたちがコンパイラを修正するにつれ、もともとの強い構造は次第に無定形な追加物によって弱められていった。
- これは、プログラムテキストと文書には中核となる設計理論を保存するうえで限界があることを示している。
事例 2: 大規模リアルタイムシステム
- 約20万行規模の産業用リアルタイムシステムの事例が示される。
- 設置と欠陥診断を担当したプログラマたちは、システム設計初期から長期間にわたりシステムと密接に結びついていた。
- 彼らは欠陥を診断する際、主に自分たちの即時的なシステム理解とコメント付きコードに依存していた。
- 一方、文書と教育を受けた外部の運用プログラマたちは、繰り返し困難に直面した。
- 製造元の熟練プログラマたちは、その問題を容易に解決した。
- 結論:
- 大規模プログラムの保守と修正は、プログラムと長く関わってきた人々の持つ知識に本質的に依存する。
- 文書化された説明だけでは、その知識を完全には代替できない。
Ryleの「理論」概念
- NaurはGilbert Ryleの理論概念を取り入れる。
- 理論を持つとは、単に命題を知っていることではない。
- 何かを行うことができ
- そのことを説明でき
- 質問に答えられ
- 自分の判断を正当化できる状態である。
- 知的な活動は、必ずしも規則に従う活動へ還元されない。
- 規則に従うこと自体も知的に行われなければならないからである。
- 規則に従う方法にさらに別の規則が必要だとすると、無限後退が生じる。
- したがって知的活動は単なる規則実行ではなく、状況の類似性を見抜いて適切に対応する能力を含んでいる。
理論は規則として完全には表現できない
- ある理論を持つ人は、現実のさまざまな状況のあいだにある意味のある類似性を見出す。
- しかしそのような類似性は、明確な基準や規則として完全に表現するのが難しい。
- 例:
- 顔立ちの似かよい
- 旋律の類似性
- ワインの味の類似性
- 同じようにプログラミングでも、新しい要求が既存構造とどう似ているか、どこに統合すべきかは単純な規則に還元しにくい。
- この点が暗黙知の核心である。
プログラマが持つべき理論
- プログラムの理論を持つプログラマは、次のことができなければならない。
1. 現実世界とプログラムの対応を説明できなければならない
- プログラムの各部分が、現実世界のどの活動や概念に対応しているのかを説明できなければならない。
- 逆に、現実世界のある活動がプログラムの中でどのように表現されているかも説明できなければならない。
- 何が関連し、何が無関係かを判断するには、現実世界全体への理解が必要である。
2. プログラムがなぜそのようになっているのかを正当化できなければならない
- プログラムの構造と詳細実装が、なぜそのように設計されたのかを説明できなければならない。
- この正当化には、規則、推論、設計原則、定量的推定などを用いることができる。
- しかし最終的にどの原則を適用するかを判断するのは、プログラマの直接的な洞察にかかっている。
3. 新しい修正要求に建設的に対応できなければならない
- 新しい要求が既存プログラムのどの機能や構造に似ているかを見抜けなければならない。
- その類似性にもとづいて、修正が既存の理論に自然に統合されるよう設計できなければならない。
- この能力は、文書化された手順だけでは代替しにくい。
プログラム修正とコスト
- ソフトウェアは必然的に修正される。
- 利用の過程で新しい要求が生まれ
- 現実世界の条件も変化するからである。
- 既存プログラムを修正するほうが、新しく作るより安いとよく考えられている。
- しかしNaurの観点では、この期待が常に妥当とは限らない。
- プログラム修正のコストは、テキスト編集のコストではない。
- 中核的なコストは、既存プログラムの理論を理解し
- 新しい要求をその理論の中へ統合することにある。
- したがって、コードが容易に編集可能なテキストであるという事実だけで、修正が容易だとは言えない。
柔軟性の限界
- プログラムに将来の変化に備えた柔軟性をあらかじめ入れておこうという主張は、部分的にしか妥当しない。
- 柔軟性はただではない。
- どの未来の状況に備えるかを決め
- パラメータや構造を設計し
- 実装、テスト、説明のコストがかかる。
- その有用性は不確実な将来の出来事に依存している。
- したがって柔軟性は、変化対応の一般解にはなりえない。
- 重要なのは、あらゆる変化に備えた構造を事前に入れておくことではなく、変化が来たときにプログラムの理論にもとづいて適切に判断する能力である。
良い修正と悪い修正
- 同じ外部動作を満たす修正でも、実装の仕方は複数ありうる。
- 表面上はどれも正しく見えるかもしれない。
- しかしプログラムの理論という観点では差が大きい。
- ある修正は既存理論を自然に拡張する。
- ある修正は既存構造の上に継ぎ足したパッチのように機能する。
- 後者の修正が繰り返されると、プログラムはしだいに継ぎはぎだらけになる。
- プログラムの長期的な生存可能性は、各修正が既存理論にどれだけよく根づいているかにかかっている。
プログラムの生、死、復活
プログラムの生
- プログラムの理論を持つプログラマたちが、なおそのプログラムを能動的に制御しているとき、そのプログラムは生きている。
- 彼らは修正要求に知的に対応できる。
プログラムの死
- プログラムの理論を持つチームが解体されると、プログラムは死ぬ。
- 死んだプログラムでも、なお実行でき、有用な結果を出せることはある。
- しかし修正要求に適切に対応できなくなったとき、その死が明らかになる。
プログラムの復活
- 新しいチームが既存プログラムの理論を再構築しようとする試みである。
- Naurは、これは厳密な意味では不可能だと見る。
- 文書とコードだけでは、元のチームが持っていた理論を完全には復元できないからである。
- 復活が可能だとしても高コストで困難であり、元の理論とは異なる理論を生み出す可能性が高い。
- 場合によっては、既存コードを救うよりも、新しいチームが問題を新たに解き直すほうが良く、しかも安いこともある。
方法論への批判
- Naurはプログラミング方法論を、「プログラマがどの順序で何をすべきかを定めた規則の集合」と見なす。
- 理論形成という観点からは、この意味での方法論はプログラミングの本質を捉えていない。
- 理由:
- 理論形成には決まった順序がない。
- 理論は本質的に部分の線形的な組み合わせではない。
- 記法や文書形式は理論形成を助けることはできても、理論そのものではない。
- したがって、プログラミングの一次的活動について普遍的に正しい方法は存在しない、という結論になる。
方法論が完全に無価値という意味ではない
- Naurが否定しているのは、機械的に良い設計を保証する手続きとしての方法論である。
- 方法論、設計技法、記法、検証技法には教育的価値がありうる。
- 良い事例、構造化原理、検証技法に慣れたプログラマは、より良い理論を形成できる可能性が高い。
- しかし、どの技法をいつ、どの順序で適用するかは、実際の問題を理解したプログラマの判断に委ねられるべきである。
プログラマの地位
- プログラミングを工業生産のように見ると、プログラマは交換可能な部品のように扱われる。
- 手続きと規則に従えば、誰でも同じ結果を出せるという見方である。
- Naurはこの見方を退ける。
- プログラムの中核成果物がプログラマの持つ理論であるなら、プログラマは容易に交換可能な労働者ではない。
- プログラマは、コンピュータを含む活動全体を責任を持って発展させ管理する専門職に近い。
- したがってプログラマには、継続的な地位と責任が与えられるべきである。
- 教育も、単なる文法、記法、データ処理技術を超えて、理論形成能力を育てる方向であるべきだ。
XPのメタファーと理論形成
- XPの「メタファー」は、Naurの理論形成という観点でうまく説明できる。
- 良いメタファーは、チームがプログラム構造について似た推測を行えるよう助ける。
- 例:
- プログラムを「組み立てライン」として理解する。
- プログラムを「レストラン」として理解する。
- 良いメタファーは、単なる比喩ではない。
- 設計者がどのような構造を期待すべきか
- 新しいコードをどこに追加すべきか
- 他人が作ったコードとどう噛み合わせるべきかを判断させてくれる。
- チームメンバーが多く、並行作業が多いほど、共有されたメタファーの価値は大きくなる。
- 共通理論がなければ、各プログラマがそれぞれ独自の理論を作り、システムはしだいに不整合で複雑になっていく。
文書化の役割
- 文書はプログラムの現在状態に完全には追いつけない。
- だからといって文書が不要というわけではない。
- 文書の目的は、すべてを記録することではなく、次のプログラマが適切な理論を形成できるよう助けることである。
- 良い文書は、読者の記憶と経験を刺激し、正しい思考経路を開いてくれる。
- そのような文書は、単に現在のクラス、関数、モジュールの一覧を並べる文書よりも長く生き残る。
良い設計文書の構成
- 経験豊富な設計者は、通常次の項目から文書を書き始める。
- 中核メタファー
- 主要コンポーネントの目的説明
- 主要コンポーネント間の中核的相互作用を示す図
- この3つは、次のチームが設計理論を形成するうえで大きな助けになる。
- ソースコード自体も理論伝達の手段である。
- 一貫した命名
- 単純な構造
- 予測可能なパターン
- 不要な例外の最小化
- 「クリーンコード」のかなりの部分は、読者がシステムについて一貫した理論をどれだけ容易に形成できるかに関係している.
まだコメントはありません。