パソコンでプログラミングしよう ウィンドウズC++プログラミング環境の構築
1.6.3.6(15)
プログラミングパラダイム

プログラミングパラダイムとはプログラミングにおけるパラダイムである。

その他の外部情報

本サイトでの解釈

"パラダイム"、"パラダイムシフト"は元々はトーマス・クーンにより創出された科学史の概念であったが、1980年頃に流行語化し様々な分野で勝手に拡大解釈され現在に至る。"プログラミングパラダイム"はそういった拡大解釈の一つと見なされる。

プログラミングパラダイムの分類

以下の表はウィキペディア(英語)概要を日本語に単純置き換えして作成した分類であるが、"論理プログラミング"、"数理プログラミング"がいかなるパラダイムであるかサイト作成者は知らない。

プログラミングパラダイム
プログラミング 命令型プログラミング 手続き型プログラミング
オブジェクト指向プログラミング
宣言型プログラミング 関数型プログラミング
論理プログラミング
数理プログラミング

パラダイムはプログラミングの属性だが、通常はプログラミング言語の属性として語られる。我々の目に触れるプログラミング言語のほとんどは命令型プログラミングの範疇にある。パソコン登場以降の最大のパラダイムシフトは手続き型プログラミングからオブジェクト指向プログラミングへの移行とされる。

上記以外の分類によるパラダイムも無数に存在し、ウィキペディア(日本語)の羅列が示すように全てを系統立てる事は不可能である。C++は複数パラダイムによるプログラミングを可能とするマルチパラダイム言語と称するが、パラダイムが無数にある以上あらゆるプログラミング言語はマルチパラダイム言語たり得る。

オブジェクト指向プログラミングと総称プログラミング

本サイトはC++が可能とする多数のパラダイムのうち二つを重要視する。

  • オブジェクト指向プログラミング
  • 総称プログラミング(ジェネリックプログラミング)

両者は共に何らかの対象を抽象化する手段で、概念としての差異は小さい。そもそも広義にはプログラミング全てが対象を抽象化する作業であろう。C++プログラミングにおける抽象化は概ね以下とされる(Matthew H. Austern, Generic Programming and the STL, Boston, Addison-Wesley, 1998; Boston, Addison-Wesley, 2001, pp.xvi-xvii)。

抽象化 対象 構文
サブルーチン 手続き 関数
抽象データ型 データ クラス
オブジェクト指向プログラミング クラス 抽象クラス/具象(コンクリート)クラス
総称プログラミング 関数、クラス テンプレート
覚え書き
この表の抽象化分類名は参考文献に基づく。"抽象データ型"は抽象クラスではなく、参考文献はクラス一般を参照する。"オブジェクト指向プログラミング"は広範な概念だが、参考文献はその一部であるクラス継承を参照する。

総称プログラミングを実現する構文をテンプレートとしたが正確ではない。多くの場合テンプレートは総称プログラミングを目的とする構文と見なせるし、その最大の果実である標準テンプレートライブラリをC++に実装するためテンプレートが導入されたとしても過言でない。しかしその構文は(クラスがオブジェクト指向プログラミングに束縛されているのと対照的に)総称プログラミングに束縛されておらず、例えばメタプログラミングという他の重要な技法を実現する。

オブジェクト指向プログラミングと総称プログラミングの対象は重なる。例えばどちらもクラスを抽象化する。

パラダイム 抽象 具象 多態性
オブジェクト指向プログラミング 抽象クラス 具象クラス 実行時(動的)
総称プログラミング コンセプト モデル(クラス一般) コンパイル時(静的)

総称プログラミングにおける"コンセプト"とはクラスの備えるべき特性であり、例えば必須とするメンバ関数(名前、シグネチャ)を定義する。少なくともC++17に至るまで文法にコンセプトを表現する構文が用意されておらず、プログラマの意識内にのみ存在する。"モデル"とはコンセプトを満たすクラス一般である。

複数のクラスを同一の抽象(抽象クラスあるいはコンセプト)として扱うことを多態性と呼ぶ。厳密でない慣用表現によれば、オブジェクト指向プログラミング(あるいはクラス)は動的多態性を実現し総称プログラミング(あるいはテンプレート)は静的多態性を実現する。動的多態性は実行時に抽象が具象化する。例えば以下であり、抽象(抽象クラス)は構文で明示される。

#include <iostream>
class Abstract
{
public:
virtual const char* GetName() const=0;
};
class Boy:public Abstract
{
public:
virtual const char* GetName() const {return "Jack";}
};
class Girl:public Abstract
{
public:
virtual const char* GetName() const {return "Betty";}
};
void WhoAreYou(const Abstract& kid)
{
std::cout<<kid.GetName()<<std::endl;
}
int main()
{
WhoAreYou(Boy{});
WhoAreYou(Girl{});
return 0;
}

静的多態性はコンパイル時に抽象が具象化する。例えば以下であるが、抽象(コンセプト)を明示する構文は今のところ用意されていない。

#include <iostream>
class Boy
{
public:
const char* GetName() const {return "Jack";}
};
class Girl
{
public:
const char* GetName() const {return "Betty";}
};
template<typename T> void WhoAreYou(const T& kid)
{
std::cout<<kid.GetName()<<std::endl;
}
int main()
{
WhoAreYou(Boy{});
WhoAreYou(Girl{});
return 0;
}

C言語の抽象化記述能力を平面上の1点(原点)と仮定しよう。オブジェクト指向プログラミング(クラス)でC++の抽象化記述能力は広がり原点を通過する直線となった。総称プログラミング(テンプレート)の抽象化記述能力はオブジェクト指向プログラミングのそれに匹敵し、原点で直交する別直線となった。二つのパラダイムを備えるC++の抽象化記述能力は2直線を直交軸とする平面であり、C言語に比較すれば無限に等しい。このユニークな見解の出典をサイト作成者は残念ながら思い出せないが、何より標準テンプレートライブラリがそれを証明する。