プログラミングパラダイムとは、プログラミング言語やプログラム設計を「何を重視して表現するか」「どういう形で問題を解くか」によって分類した考え方です。多くの言語は単一のパラダイムに縛られず、複数のパラダイムをサポートします。パラダイムはプログラムの書き方、データの扱い方、状態変化(副作用を許すかどうか)や実行の順序性などに注目して分類されます。
パラダイムは大きく分けて、命令的(インペラティブ)パラダイムと宣言的パラダイムの二つに分けられます。命令的な考え方は「どのように実行するか(手順)」を重視し、宣言的な考え方は「何を達成したいか(目的)」を重視します。実際の言語では両方の要素を併せ持つことが多く、状況に応じて使い分けます。
内容
1 インパーティブプログラミング
2 宣言的プログラミング
3 その他のパラダイム
4 概要
5 パラダイムの問題点
6 歴史
6.1 マシンコード
6.2 手続き型言語
6.3 オブジェクト指向プログラミング
6.4 宣言的パラダイム
7 関連ページ
8 参考文献
9 その他のサイト
命令型(インペラティブ)プログラミング
命令的プログラミングでは、プログラマーは、コンピュータに実行すべき順序付けられたステップの集合を与えます。具体的な手続きや制御フロー(ループ、条件分岐、代入など)を使って「どのように」目的を達成するかを記述します。例えば、コンピュータに猫の絵を描かせるなら「ここに円を描いて、そこに二つの小さな円を描いて、上に二つの三角形を描いて」のように命令を列挙します。命令型のプログラムはしばしば変数と状態の変化を伴い、副作用が多いことがあります。
命令型の中にもいくつかの主要な流派があります。多くの言語はこれらを組み合わせています。
- 構造化プログラミング - プログラムは明確な構造(順次、選択、反復)で記述され、無秩序なジャンプ(例えば goto文)の多用を避けます。読みやすく、保守しやすいコードを書くことを目的とします。
- 手続き型(プロシージャル) - 命令のリストに名前を付けて再利用可能な「手続き」や「関数」を定義する方法です。大規模なプログラムを小さな手続きに分割して管理します。C や Pascal などが典型です。
- オブジェクト指向(OOP) - オブジェクト指向では、データとその操作を「オブジェクト」にまとめ、オブジェクト同士のメッセージ交換やメソッド呼び出しを通じて振る舞いを定義します。状態と振る舞いを結び付けることで設計上の抽象化を行います。Java、C++、C#、Python などが代表的です。
利点:命令的手法は直感的で、低レベルな制御(メモリ管理や最適化)を行いやすく、逐次処理の流れを明確に記述できます。一方、欠点は副作用や共有状態に起因するバグが発生しやすく、並行処理の設計が難しくなる点です。
宣言的プログラミング
宣言的プログラミングでは、プログラマーは「どのように実行するか」ではなく、何を達成したいかを記述します。例えば猫の顔を描かせるなら「顔を描いて、2つの目、2つの耳、口を描いて」といった結果を指定します。実行方法(アルゴリズムや手順)は言語実装やランタイムに委ねられます。
代表的な宣言的パラダイム:
- 機能性(関数型) - 副作用の少ない純粋関数、イミュータブルなデータ、第一級関数や高階関数、再帰を多用します。参照透過性によりテストや並列化が容易になります。Haskell、OCaml、Erlang、Clojure、Scala(部分的)などが例です。
- 論理 - 事実とルール(約束事)を宣言し、問い合わせ(クエリ)を投げて推論エンジンに解を求めます。Prolog が代表例です。
- イベント駆動型 - 「何が起きたか(イベント)」に応じてコードの一部が実行されます。GUIや非同期プログラミング、サーバーサイドのイベント処理などで使われます。JavaScript のブラウザ環境や Node.js のような環境が典型です。
- 宣言的なデータ操作言語(例:SQL)やマークアップ言語(例:HTML/CSS)も、何を表現したいかを記述する宣言型の一種です。
利点:宣言的アプローチは副作用を抑え、抽象度を高めることでコードの簡潔さと保守性を向上させます。欠点としては、低レベルな最適化や詳細な制御が必要な場面では不得手なことがある点や、実行時の振る舞いが抽象化されるためパフォーマンスの理解が難しい場合がある点が挙げられます。
その他のパラダイム
多くのパラダイムは命令型と宣言型のどちらか一方に完全に属するわけではなく、両方にまたがって現れます。以下は実務でよく話題になる追加のパラダイムと概念です。
- 並行・並列プログラミング - スレッド、コルーチン、アクター、並列ストリームなど、複数のタスクを同時に扱うための設計と抽象。
- リアクティブ/データフロー - データの流れと変化に反応して処理が駆動されるモデル。ストリーム処理やリアクティブUIで利用されます。
- アスペクト指向 - ロギングやトランザクション管理のような横断的関心事をモジュール化する手法。
- 関心分離・ドメイン固有言語(DSL) - 特定の問題領域に特化した表現や構文を用いることで可読性・生産性を高めます。
これらは単体で使われることもありますが、多くは上で挙げた命令型・宣言型パラダイムと組み合わせて用いられます。言語やフレームワークはこれらの手法のいくつかを組み合わせることで柔軟性を持たせています。
概要
パラダイムは「ものの見方」であり、どのアプローチが最適かは問題領域、チームの慣習、性能要件、並行性の必要性などによって変わります。一般的な傾向として:
- 低レベルな制御や最適化が重要な場合は命令型が適している。
- 並列性・安全性・テストしやすさが重要な場合は関数型や宣言的手法が有利なことが多い。
- 複雑なドメインのモデリングや大規模開発ではオブジェクト指向が有効に働くことがある。
パラダイムの問題点
パラダイムには明確な境界があるわけではなく、用語や分類は文脈によって変わります。いくつかの注意点:
- 「この言語は○○型だけだ」という考えは誤解を招くことが多い。多くの言語はマルチパラダイム設計であり、開発者は状況に応じて最適な手法を選ぶ必要があります。
- 異なるパラダイムを混在させると設計が複雑になり、学習コストやチーム内の一貫性に影響することがある。
- 特定のパラダイムを盲目的に信奉すると、実際の要求に対して最適でない選択をするリスクがある。
歴史
プログラミングパラダイムの発展はコンピュータ技術の進化と密接に関係しています。
マシンコード(機械語)から始まり、次にアセンブリ言語や初期の高水準言語が登場しました。手続き型・構造化プログラミング(Fortran、Pascal、C など)はプログラムを手続きや関数で分割して可読性と再利用性を高めました。続いてオブジェクト指向(Smalltalk、C++、Java)がソフトウェアの設計スケールを拡大しました。近年は多コア環境の普及や安全性への要求から、関数型や宣言的手法、リアクティブ設計が再び注目されています。
各時代で新しいパラダイムが登場した背景には、ハードウェアの変化、ソフトウェアの複雑化、並行性や分散システムの必要性などがあります。現在では、言語やフレームワークは複数のパラダイムを取り入れ、実務上の問題を柔軟に解決できるよう進化しています。
以上がプログラミングパラダイムの主要な概観です。用途や要件に応じてそれぞれの考え方を理解し、適切に組み合わせて使うことが実践上重要です。

