哲学からオブジェクト指向を考える
クラスとオブジェクトはプラトンのイデア論に似ている?
この記事の内容は何らかの結論に至るものではない。この問題について思考しきれておらず、結論めいたものすらない。こうかも知れないという洞察は得たものの、まだ資料による裏付けがない。つまり、アイデアは降ってきたが検討・検証しきれてない状態だ。それでもこれを書き留めておくことには意義があると思い、秋を感じさせる涼しく心地良い風が吹く夜の酔いに任せて筆を取ったものである。
オブジェクト指向というものを何か哲学的に考えられないものか。この問題意識は自分の中で長らく放置されていた。ソフトウェアエンジニアになってまだ1ヶ月か2ヶ月の頃、自分はまだクラスとオブジェクトの違いも分からなかった。
そんな折、指導係の先輩とランチに出かけた。場所は東日本橋、川沿いの雑居ビルに入っている中華料理屋だった。昼時だというのに客の入りは良くない。二人で窓際の席に座って話すうちに、クラスというのは型みたいなもので、オブジェクトというのはそれを元に作られたものだという説明をしてもらった。
それを聞いた自分は「まるでプラトンのイデア論みたいですね」と言っても先輩はピンときていないようだった。そこで洞窟の比喩を持ち出して説明したものの、やはり納得いっていないご様子。まあ、哲学とプログラミングは全く異なるものかと思い話題を変えることにした。
しかし、ここで話したことは今でも鮮明に覚えている。それは何かもっと抽象的な、根本的な視座から自分たちが生業としているプログラミングというものを捉えたいという気持ちを抱いたからだった。
時は流れて2024年、自分もソフトウェアエンジニアとして経験を積んで5年以上経った。上記のような思索は「どうせ手がかりがない」と諦めていた。しかし、今年に入ってプラトンの著作を何冊か読んだり哲学史の概説本を読んだりするうちに、最近になってまた一つ考えてみるかという気力が湧き起こった。
哲学の視点からオブジェクト指向を捉える
そこでまず先人はいないかと調べてみると、あるWebページに以下のような記述を見つけた。
巷の技術者向け書籍を読んで何か物足りない、薄っぺらな感じがするものが多い。哲学が感じ取れない。(中略)名著には技術以前に哲学があり、思想がある。我々が学びとるのは単に実践的なテクニックのみで良いのだろうか?(略) 工学には科学の裏付けがあり、科学には哲学の裏付けがある。本来そうあるべきであろう。 連載 オブジェクト指向と哲学 第1回
これこそまさに自分がプログラミング(というよりコーディングに矮小化したほうがいいかも知れない)という営みに感じていたことだった。この文章を読んだときは先達に向かって僭越ながら我が意を得たりという心持ちだった。「コードを書いてユーザーに価値を届ける」という言い回しは聞き心地のいい甘言ではある。しかし、目の前で我々が書いているこのコードとは一体何かという問いには答えていないように感じていたのだ。
「オブジェクト指向と哲学」というエッセイをいくつか読むと、プラトンの哲学であるイデア論を引いてオブジェクト指向を説明したり、『プロタゴラス』という徳とは何かについてソクラテスが議論する対話篇で説明される徳についてUMLを用いてモデリングをしたり、アリストテレスの形相(エイドス。form)と質料(ヒュレー。material)を用いてまたオブジェクト指向を説明しようとしている。ただし、その試みが成功しているか否かについては読者の判断に任せるしかない。
なお、一言断っておかなければならないのは、私がここでいうオブジェクト指向というものはアラン・ケイが考えている本来ものではない。メッセージパッシングとは無縁な、クラスとオブジェクト、プロパティとメソッドのような矮小化されたものである。それでも自分はこれについて一通り考えを述べてみたいのだ。
クラスとは何か
そもそもクラスとは何か。プログラミングの概説書ではオブジェクト指向におけるクラスとは、型のようなものだと説明される。クラスをインスタンス化するとオブジェクトが生成される。クラスはオブジェクトの型のようなものなのだと。実際、プログラミング言語はクラスそのものを操作するのではなく、メモリに乗せたオブジェクトを操作している。
ここで一つ疑問が生まれる。クラスとは果たして実体と言えるのか。プログラミングの世界にはEntityという用語があって、これを直訳すると実体という意味である。しかし、クラスという実体はこの世界を見渡してもどこにも存在しない。コードというテキスト上に表現されたものであり、これが何かコンピュータの外の物体や概念を指すことはない。
例えば、Bookクラスがあるとする。書籍にはタイトルがあり、著者がいて、値段がある。
Class Book {
title: Title
author: Author
price: Price
// …
}
この時、このBookクラスは何を指示しているのだろうか。私は何も指していないと考えている。なぜなら、「書籍にはタイトルがあり、著者がいて、価格が設定されている」などということは一般論でしかないからだ。
タイトルがない書籍もあるだろうし、価格が設定されていない書籍もあるだろう。何を持って書籍とするのか、書籍を書籍たらしめているものは何か。タイトル、著者、価格が設定されていれば書籍と言えるのか。そのような疑問にぶつかる。
デカルトは座学の限界を知り「街という大きな書物を読む」ためにオランダなどの諸国遍歴の旅に出た。比喩表現だと分かった上でだが、この本にはタイトルがあって著者がいて値段がついているだろうか。そんなことはないだろう。
唯名論を手がかりにクラスを考える
この問題を考えるにあたり、何か手掛かりになることはないかと考えてみる。そこで思い出されるのはトマス・アクィナスの唯名論だ。「普遍的なものは名前(名詞)の上にしか存在しない」という有名な考え方である。彼は神学者なのでここでいう普遍(universe)はすなわち神だ。ただ、ここでは神ではなく書籍について考えている。そこでこの思想を援用すると「書籍というものはこの名詞にしかない」と言われれば、なるほどその通りだと思える。
我々は書籍というものを生まれながらの知識として持ってはいない。感覚を通して得た経験から、何かを「書籍である」「書籍ではない」と判断し呼び分けているだけだ。目の前にある個別具体的な書籍をあなたは必ず見たことがあるだろう。何冊も持っていて、書棚を埋め尽くしているかも知れない。お気に入りの一冊もきっとあるはずだ。
しかし、一般的で抽象的な書籍というものはこの世には存在しない。それは概念として人間の頭の中にあるだけだ。この抽象的な書籍を手に取ってみることはできないし、ましてや読むことなんてできない。
プログラミングにおいて、クラスとして表現されるものはただの一般名詞なのである。それゆえに、いいエンジニアはクラスや変数の名前にこだわる。ドメイン駆動開発で「命名は業務で普段使われている言葉を反映すると良い」(ユビキタス言語)と言われているのはこれが理由の一つでもあるだろう(これを推し進めるとウィトゲンシュタインの言語ゲームの視点から考察したほうが説明しやすいのだがここでは触れない)。
クラスを具体的なコンテキストに置いてみる
Bookというクラスはあまりに一般的すぎる。そうではなくて、これを何らかのドメイン、何らかのコンテキストに置くことで見えてくる一側面を取り出す必要がある。
本と一口に言っても「本屋で売られている商品としての本」「夏休みの課題図書」「映画の特典として無料で貰える書籍」「自宅の書斎の本棚に並んでいるもの(蔵書)」「積読本」「すでに読んだ本」と様々である。
例えば商品としての本は以下のようにモデリングできるだろう。
Class SalableBook {
title: Title
author: Author
price: Price
stock: Quantity
public function isOutOfStock() {
// …
}
// …
}
ここでは、販売されたかどうか、販売可能かどうかということに焦点が当たる。本屋の書籍は商品だからだ。「夏休みの課題図書」は例えば中学生向きか、高校生向きかという区分や、古典か最新の小説かなどというジャンルが重要になるだろう。蔵書などは横幅と高さを設定して本棚の一角に収まるのかや、重量に関心を持って重さで床が抜けないかという点に関心を持つかも知れない。
そしてこれら具体的なコンテキストに置かれたクラスは、明らかにそのシステムやサービスが対象とする現実の書籍という存在を対象としている。より正確には、現実にある複数の書籍の一側面を切り取ったもの(抽象化したもの。特徴を抽出したもの)だ。
複数という要素が重要で、この世に唯一ものもはクラス化しないのではないか。例えば、この記事を読んでいる「あなた」という存在はシステム上クラス化するのは適切ではないだろう。ある会社に勤める「従業員」としてのあなた(Employeeクラス)や、銀行口座を開くときの「顧客」としてのあなた(Customerクラス)であれば、システムはクラス化して管理できるだろう。
従業員という観点からは、あなたの健康状態や年齢、職歴、給与、住所などの一側面にしか興味がなく、銀行の顧客としてのあなたは上記に加えて、資産総額や家族構成に興味を持たれるだろう。このように、クラスというものは現実に存在する物事(対象)の一側面を抽出したものである。この辺りは、DCIアーキテクチャの考え方と一致するのかも知れない(が、それについては自分は詳しくないので何とも言えない)。
このように考えると、カントのカテゴリー論(認識論)もクラスとオブジェクトの考察に使えるような気もするが、今の私には荷が重い。そもそもここで語っているオブジェクト指向ですらクラスの話でしかなく、継承やインターフェース、ポリモーフィズムといった話題にも触れていない。それにどの考え方も聞き齧ったことをもとに書き散らしているだけだ。資料で確認しておらず正確性に欠けるしツッコミどころも少ない。酔いも覚めてきたのでここらで筆を置くこととする。
Happy Coding 🎉