コンピュータやプログラミングについて語りたい! と思って、あれやこれや考えてみると、コンピュータとはつくづく抽象のカタマリだな、と思うに至った。
いきなり何を言ってんだという感じだが、コンピュータについて何を語るにしても抽象のレイヤーを自由自在に切り替えないと私にはまともに説明できそうにない。いや、上手い人ならそこを誤魔化して抽象を意識させずに説明できるのかもしれないが、私には無理だ。
だったらむしろ、先に抽象について語っておいた方が後々説明もしやすいし、その方が良い気が俄然してきたので、今回は「抽象」とその対義語とされる「具体(具象)」について思うところを語っておきたい。
具体と抽象
そもそも抽象とは何か。色々な説明方法があるとは思うが、とりあえずここではなにがしかの個別の事象から一部分の要素を抜き出したもの、ということにする。逆に具体とは、なにがしかの事象に個別の要素を加えたものとする。また要素を抜き出したり加えたりした「もの」もまた別の事象と捉えることにする。
といっても良くわからないと思うので、とりあえず車を例にして考えてみよう。車は車でも「乗用車」といえば、だいたいが4人乗りくらいで全長が3~5mくらい、原動機(エンジンやモーター)が付いててドライバーが進路を自由に決めて移動することができる乗り物だ。
この「乗用車」から何でもいいので一部分の要素を抜き出す。「原動機がついてて進路を自由に決めて移動することができる乗り物」という部分を抜き出せば、これはいわゆる「自動車」のことだ。そしてこれから更に「移動する乗り物」という要素を抽出すれば「移動手段」とかになるかなと思う。こういうふうに事象から要素を抽出する操作を抽象化という。
逆に「自動車」に個別の要素を加える。「全長11mで定員80人」という要素を加えれば、まぁ多分「バス」くらいしかなさそう。これにもっと細かい形状とか材質とかスペックの要素をどんどん加えるとバスはバスでも「特定の車種」になるし、車番とか加えると「特定の車両」になる。こういうふうに具体的な要素を加える操作を具体化という。
ここで覚えておいて欲しいのは、具体と抽象には何階層もあるということだ。車の例えでは、とりあえず乗用車、自動車、移動手段の3階層で考えてみたが、もっと細かく階層を分けることもできる。それぞれの中間の層やその外側の層だ。分け方次第で実質的に無限の階層があると考えて良い。
そして、この階層(レイヤー)の分け方はその時々で都合の良いように決めれば良い。
ハードウェアとソフトウェア
ところで車の例からもわかるように、抽象化すればするほど実体のない概念的なものになるし、逆に具体化すればするほど実体を伴った物理的なものになる。
ここでコンピュータの文脈でいうハードウェアとソフトウェアについて考えてみる。ハードウェアとは物理的な機械のことだし、ソフトウェアとは実体のないプログラムやデータのことだ。これは具体と抽象の関係にあると考えることもできる。
例えばコンピュータに 1 + 1 という計算をさせたら 2 という結果になったとする。だがコンピュータをどれだけ分解しても 1 や 2 、はたまた足し算などと言う物体は見つからない。あるのは電子とか電場とか、微細な凹凸とか結晶とかそんなものだ。数や演算というのは純粋な概念なので実体が存在しなくとも不思議はない。
だが、電子や電場の作用を抽象化すると電流や電圧になるし、電流や電圧の大小というものを抽象化して電子回路が実現されている。これを更に抽象化することで数や演算という概念が表現されている。このように抽象化して実体がなくなると純粋な概念を表現することができるようになる。
そして数や演算という概念を更に抽象化して、意味やロジックの組み合わせとしたもの、これがいわゆるソフトウェアと呼ばれるものの正体だ。
念のために補足しておくと、コンピュータが 1 + 1 を計算して 2 を算出する、という一つの現象に、電子の作用という事象が存在すると同時に数や演算という事象が存在しているのだ。バスはバスであると同時に自動車でもあるし、適切に運行されていれば移動手段という捉え方ができるのと同様に、電子は電子であると同時に電流でもあるし、適切に回路が組まれていれば数や演算という捉え方ができる、ということだ。どの抽象のレイヤーで事象を捉えたか、という表現の違いでしかない。
とりあえず、同じ現象について説明しているのに、抽象のレイヤーによってその表現が違うことがある、ということを認識しておいて欲しい。場合によっては、抽象のレイヤーが異なる説明を混ぜるとお互いに矛盾しているように見えることもあるので混乱しないように気を付けて欲しい。
抽象化と比喩と共通点
この記事の冒頭で、コンピュータの話をするのに抽象の考えがないと説明が難しい、というようなことを宣言した。抽象について多少の説明はできていると思うので、もう少し身近なコンピュータにまつわる抽象化を見てみよう。
皆さんのお近くの机を見て欲しい。その上にゴミ箱はあるだろうか。机の天板に窓があったりしないだろうか。
ゴミ箱くらいならともかく机の天板に窓がついていることは普通はない。しかし、こんなことがコンピュータ界隈では日常茶飯事なのだ! というのは、デスクトップにゴミ箱があったりアプリの表示領域をウィンドウと呼ぶことを茶化したジョークだが、これも抽象化の一例だと考えることができる。
コンピュータのゴミ箱は現実のゴミ箱から「不要な書類(ファイル)を一時的に捨てる場所」とか「入れてすぐなら取り出せる」などの要素を抜き出したものだろう。デスクトップは「書類(ファイル)とか広げて作業する場所」、ウィンドウは「こっち側とあっち側の境界」のような要素を抜き出したものなんじゃないかなと思われる。
ところでなぜコンピュータのゴミ箱も「ゴミ箱」という名前なのだろうか。車の例では抽象化や具体化した事象には別の名前を付けて呼んでいた。それに対してこちらは全く同じ名前で呼んでいる。
これはいわゆる比喩だと考えることができる。事象としては別物だが共通点に着目してもう一方の性質などを借りてくる表現手法だ。「不要なものを一時的に捨てて云々」という性質がどっちも同じなんだから、ゴミ箱と呼んでも差し支えないだろう、という考えだ。比喩としてゴミ箱と呼んだ方がわかりやすかろうという配慮かもしれない。
また、区別する必要がなければわざわざ新しい名前を考える必要もない、ということもあるだろう。なんかホニョペニョコとか違う名前を付けて区別することもできるだろうが、同じ名前で不都合がなければ新しい名前を考えるコスト、新しい名前や概念を覚えるコストが削減できる。
逆に考えて、名付けするということは他の事象と区別する必要がある、ということだ。自動車というものがバスしかないなら「バス」か「自動車」のどちらかの名前はなくても困らない。
抽象化したものにわざわざ名前を付けて区別するということは、抽象化すると同じものになってしまう別の事象が存在するということだろう。この観点から抽象化という操作を見ると、抽象化とは異なる事象から共通点を括りだす操作と考えることもできる。実際、物事を考えるときに抽象化が必要な場面というのは、複数の事象を共通化して扱いたいときがほとんどだろう。
コンピュータと抽象
ともあれ、ゴミ箱、デスクトップ、ウィンドウ、コンピュータ上のそれらを個別にみると比喩として納得できなくもないのに、全て組み合わさると何とも不思議な空間ができあがってしまう。このように抽象のレイヤーが揃ってないものが当たり前のように同居している。コンピュータ界隈ではありがちな現象だ。
ゴミ箱などは使用者からも分かりやすい抽象化の例だが、プログラミングをしているともっと高度に抽象と比喩が入り乱れていることを実感する。おそらくこれはソフトウェアが実体の存在しない完全に抽象化された概念だということと無関係ではないだろう。ハードウェアのように物理的な制約を受けないので、自由なレイヤーで実装することができる。様々な人が新しいソフトウェアを構築するたびに、その部分部分でその時々に最も都合の良い抽象や比喩を持ってきた結果だろう。
今回、抽象についてあれやこれや詭弁を弄してきたのは、そんなプログラミングのことを語る上で抽象について最低限知っておいて欲しかったからだ。
結局、比喩は比喩でしかないので本質を正確に捉えているとは限らないということもあるし、異なる抽象のレイヤーが交差することで結果的に矛盾しているように見えたりする。
しかし、そんな場合でも今回の話が理解の一助になれば良いな、と思う。逆に混乱させてしまったら、それはごめん。