プログラミングパラダイムについて、つれづれと

Software Design 2010年6月号 にのった artonさんの 関数型言語についての記事中の、プログラミングパラダイムの分類(↓)

について、Software Design 2010年6月号が面白いです - みねこあ で、

オブジェクト指向パラダイムの仲間のなかで、なんで Smalltalk だけ仲間はずれ(しかも「手続き型」にされてる)なんだろうと思ったり。(中略)
その中で比べたらかなーり Lisp っぽいのに...。すくなくとも Ruby とグループが分かれる理由はわかんない。

と、疑問を書いたところ、arton さんから、Smalltalk が (関数が第一級オブジェクトになっている等その実質の機能は別として)意図として 関数型とのハイブリッドを目指していないこと、Ruby は 同じものに collect と map の二つの名前を与えている例を示し、関数とのハイブリットを意図していると判断できる──風な回答を頂きました。

これにはすっきり納得です。

つづいて sumim さんが、Smalltalk-76の時点では関数をメソッドの引数としてしてすることが出来なかった(=第一級のオブジェクトとして扱えなかった)ことと Ruby のそれの類似性、そして SmalltalkSmalltalk-80 にて Lisp大好きGoldbergの手によって すっかり「それなんて Lisp」の仲間入りしてしまう歴史に振れた上で

この、LISP ではなく Smalltalk を模して考案された Ruby のブロック付きメソッド呼び出し機構や構文が、実は Smalltalk-76 への先祖返りという結果をもたらす「車輪の再発明」だったという実情は、LISP 似の別名を許すのと、LISP 似の機構に自らを変容させるのとでどちらが LISP 似かという arton さんの判断基準とあわせて、私には不思議で面白いなと感じられました。

コメントされていて、これにも 確かにそれはとても面白いなぁと思った次第。

そんなマイブームにのって、今週はプログラミング言語に関する本を読み返していたのです。で、せっかくなので、プログラミングパラダイムに関する記述をメモっていくエントリー。

内容とか結論は無いですので、あしからず。

ThoughtWorks アンソロジー

手持ちの本では一番あたらしくて一番無難かな、とおもえるプログラミングパラダイムに関する記述。

ThoughtWorksアンソロジー ―アジャイルとオブジェクト指向によるソフトウェアイノベーション

ThoughtWorksアンソロジー ―アジャイルとオブジェクト指向によるソフトウェアイノベーション

Rebecca J. Parsos さんによる「3章 言語の緑豊かな景観」の 3.3.1 パラダイムで、プログラミング言語パラダイムについて触れています。以下の表は「複数のパラダイムの側面を持ち合わせてるものもある」と断った上での主要なプログラミング言語パラダイムとして紹介されているものです。

分類 定義
命令型 一連の文は状態を操作する アセンブラFortran
手続き型 文をまとめたプロシージャで構成される C、PascalCobol
オブジェクト指向 オブジェクトで構成される SmalltalkJavaRuby
関数型 状態を持たない関数で構成される LispSchemeHaskell
論理型 解を求めるのに公理と推論ルールを用いる点が特徴である Prolog、OPS5
宣言型 解を求める方法ではなく、解を記述する XSLTSQLProlog

つづけて、以下のように補足されています。

この表は、共通性の少ないものが組み合わさっているように見えるかもしれません。実際のところ、この表には3つの異なる特性が入っています。
表の中には構成、状態、スコープの概念があります。

プログラミングパラダイムを描き出す側面として、構成、状態、スコープを上げ、それぞれについて、以下のような感じで例示しています。(文章を引用すると長いのでまとめてみました)

  • 構成
    • オブジェクト指向? ....オブジェクト
    • 関数型? ....関数
    • 手続き型? ....プロシージャ
    • 命令型? ....文
  • 状態
    • 命令型 ....明示的に記憶域の状態を操作
    • 関数型 ....一切の状態の操作を行わない
  • スコープ(状態に関する可視性)
    • オブジェクト指向 ....状態はオブジェクトの中にあり、オブジェクト自身だけが見える
    • 命令型 ....プログラムのあらゆるところから見えるグローバルな状態を持っている
    • 関数型言語 ....関数クロージャの中で変数を値に結合するが、この変数値を他の関数から見ることが出来ない

(パラダイムの末尾に?をつけたのものは、本文中にて具体的にどのパラダイムに対応するのか明言されていなかったので、わたしが適当したものです)

この説明では、命令型言語 と 手続き型言語 を明確にわけていて、命令型は構造化されていない(変数もスコープで隠されない、ロジックもプロシージャで構造化されない)という風に説明されています。

プログラミング言語の新潮流

artonさんが Software Design の特集の中で参考文献として挙げていた本です。

プログラミング言語の新潮流 (計算機科学・ソフトウェア技術講座 2)

プログラミング言語の新潮流 (計算機科学・ソフトウェア技術講座 2)

第1章 序論 の中で、計算モデルの分類として以下の表が掲げられています。

代表的言語
手続き型言語 FORTRAN, ALGOL 60, PASCAL, C
宣言型言語
関数型言語 ML, KRC, LISP, Scheme, FP
└論理型言語 Prolog
対象指向型言語 Smalltalk

手続き型言語については、構造化プログラミング(structured programming)*1論争の中で明確になった新しいプログラミング方法論を具体的に実現したもの、と捉えています。

関数型言語については、数学的フォーマリズムに基づくプログラミングと捉え、具体的には、数学的フォーマリングの鍵となる概念は関数であり、関数から成るプログラミング表現は参照透明性(referential transparency)であるとしています。論理型言語については、問題意識も目的とするところも関数型言語と重複するところが多いが、歴史的に関数型言語と異なった動機から生まれているとかかれています。(これら二つを総称して宣言型言語と呼ぶ、としています。)

関数型言語も論理型言語もそのようなアプローチは昔からあったもののプログラミング言語の形成には直接には結びつかず、現実のものとなったのは それぞれラムダ計算と Horn節一階述語論理 を計算のモデルとしたときであったとしています。

おもしろいな、と思ったのは「対象指向型言語」という表現です。おそらく対象=Objectの訳語ですが、日本語でこう言われると、もっと広く一般的な語義をもつ意味に見えてきますし、実際に「計算の対象」と Object は区別されずに「対象」と書かれているように見えます。

さて、その対象指向言語ですが、

対象指向型言語は,宣言型言語が形式的論理体系との結びつきによって,関数型,あるいは論理型と名づけられ分類されているのに対し,問題領域にある計算の対象をいかにモデル化するかということを強く意識して設計された言語である。

関数型言語や論理型言語においては,計算対象のモデル化が,基礎となる論文体系と深く結びついて行われる.これに対し,対象指向型言語では,対象のモデル化と対象間の関係は,計算の機構とは異なった観点から論じられる.

としています。対象指向型言語では、これまでの言語分類とは分類のときに着目する側面が違うため、直交しうる、具体的に「関数型言語や論理的言語の枠組みに基づいた対象指向型言語を考えることも出来る」と書かれています。

また、同書では Smalltalk から対象指向言語の特徴を抽出するのではなく、データ型を通して計算対象を分類し、モデル化しようとする試みを通して論じるとしており、対象指向型言語に概略ついては、

型の理論と対象指向型プログラミングとの関係を明らかにする研究はまだ始まったばかりであり,本書でそれを充分に論じることは出来ないが,型が対象指向言語と結びつく手がかりを10章の型付けプログラミング言語の中で論じている.

で締めています。

ちなみに紹介された10章は、「抽象化によって取り出される性質,あるいは性質につけた名前を型という」から始まる型について全般的で濃ゆい内容になっているのですが、OO に関わるところだけ引用すると、

  • (i) 型を型変数を用いて柔軟に表現する機能,
  • (ii) 型を型によって特徴づけられたデータとそのデータ上での演算によって定義する考え方,
  • (iii) 型と論理式とを同一視する考え方

(i)は多相型付け(Polymorphic typing) と呼ぶ機能であり最近のプログラミング言語の設計に大きな影響を能えている(中略)

(ii)は抽象データ型と呼ばれるものである.データ型は上に述べたように抽象化の結果として得られるものであるが,抽象化の見方を変えて,データ型はデータの集合の族Sとデータの集合上で定義される演算の集合Σの対 (S,Σ) であると捉えることができる.(S,Σ)を抽象データ型とよぶ.(中略)

しかし,最近の抽象データ型に関する研究の進展をみると,抽象データ型を高速に実行するプログラミング言語を考えようとするよりも,抽象データ型をプログラムの仕様記述と仕様記述の正当性を検証するための枠組みを与えるものと考えるアプローチが主流になっている.

一方,抽象データ型の理論から一歩離れて,工学的立場から,抽象データ型の考え方を計算の対象モデルに適用し,プログラミングの方法論を考えていこうとするアプローチがある.このアプローチの先駆けになったのは,シミュレーション用プログラミング言語Simula [Dahl 72]である.このアプローチの中から Smalltalk[Goldberg 84]に代表される対象指向型言語がうまれてきている.

(iii)の考え方(中略).構成的型理論では型が論理式であり,プログラムが論理式の証明であると考える.したがって,プログラミングとは証明を行うことであり,証明が完成したとき,その結果としてプログラムが自動的に生成されることになる.

(この後は型付きラムダ計算の話に続き、ほとんどは関数型言語を例に話が進んでいきます)

プログラミング言語の概念と構造

プログラミング言語の概念と構造

プログラミング言語の概念と構造

パラダイム分類よりはそれを構成する概念を主軸にかかれた本で、パラダイムという視点でうまく引用できないのですが、

本書の中心となるのは、第3章から第9章までの第II部である。その構成は次のように図示することができよう。

式から、制御フロー、手続き、モジュール、クラスを通って並行性に至る線は、命令型言語の機能をたどる道筋である。モジュールとクラスは、言うまでもなく言語の他の様式とも関連が深いので、命令型言語の観点から連続して議論する。(中略)

関数型プログラミングは、Lispの一方言である Schemeと、Standard ML を用いて説明する。論理型プログラミングは Prolog で、そして最後に Ada を用いて並行性について議論する。(中略)最終章では、ラムダ計算を用いて型について学ぶ。

となっていて、OOをモジュールの観点から説明されます。型からアプローチする「プログラミング言語の新潮流」とは対照的で面白いところですが、わたしは「新潮流」の方が好きでしょうか。


* * *


Smalltalk を 単純に「手続き型+オブジェクト指向」と分類してしまうことに、私が違和感を感じる一番の理由は、Smalltalk のメッセージ式が、手続き型とも関数型とも言い難い点にあります。

メッセージ式は if-else や while で綴られる手続きに比べ、高い抽象度を持っています。(具体例としては、コレクションクロージャメソッドが有名です)

しかし、「プログラミング言語の新潮流」では、対象指向言語を「データ型を通して計算対象を分類し、モデル化しようとする試み」というアプローチで分類しようとしており、このアプローチではSmalltalk の 計算モデルである「メッセージパッシング」そのものは、「オブジェクト指向」というパラダイムを決定づけないという見解が導けます。

よって、Smalltalk は 手続き型なのか、関数型なのか、という命題については、単純に OO と関係しないところで 「メッセージ式ってどうなの?」という話になるのでしょうか。

ぶっちゃけ、Vista Smalltalk flash のような アセンブリ言語よろしく 1対1で メッセージ式をS式 に変換してしまうような処理系もあるくらいですから、手続きと言い切るのはどうなのよと思わずにいられません。また、Software Design 2010年6月号 の特集よろしく「手続き脳」「関数脳」的に自分の ○○脳switch を見返せば、Smalltalk のコーディング時には明らかに 「手続き脳モード」とは別のモードに移行しているように感じます。

が、これを関数型言語と言いきってしまうのはもっと問題で、わたしの未熟な脳モードでも、Lispモードと Smalltalkモードは別物です。どちらに分類する?との2択は手続き型の方ですが、けれども私的感覚な問題として、もう手続きでも関数型でもない別のパラダイムに置いてしまいたい想いでいっぱいです。「メッセージ型言語」でいいじゃん、と思います。(Objective-C と Self だけが友達さ〜♪)

そんな極論の一方で、やっぱり手続きの変種なのかなぁとは思います。メッセージ式は時間と状態の概念にみち満ちていますもの。Lisp の手続き的側面をさらに濃ゆくしたものである点は Logo と同じような目的のベクトルです。

そしてLogoといえば「実体はLisp」な点からそのまま Lispとして扱う一派もいて(たとえば大学でLogoをつかう層)、この時Logoを手続き型言語と分類してしまうのはのは問題です。一方でタートル言語として用いる層にとってLogoは明らかに手続き型言語です。

そんなこんなで、言語の「目指したところ」を基に言語パラダイムを分類する artonさんのアプローチには、酷く納得が行ってしまいました。

*1:文中では構造的プログラミングと訳されている