抽象化について

Posted on August 6, 2015

この投稿を皮切りに色々な人が「抽象化」について持論を展開しているので自分も参加してみようと思う。なお、異論がある方はぜひ指摘してほしい。

ここではあえて直接的に「抽象化とは何か」を考えない。それより、特にプログラミングの文脈において、物事が抽象化される過程や必要性から「抽象化」を抽象化していこうと思う。それにしても、プログラマ間では抽象化の必要性は否定の余地がないほど合意されているはずなのに、その表象的な認識がそれぞれバラバラなのは、なかなか面白い現象だ。

概念のカスケード

こういったテーマを考えるにあたって、人間の認知的特性を理解しておくのはとても有意義なことだ。その中で特に重要なのが、人間は複数の概念を総合し新しい概念を作ることができる、という特性である。神経科学的に解明されているか知らないが、自分の感覚では、その新しい概念を想起するのに比べて、その概念を構成する複数の他の概念を想起するほうがコストがかかる。そういう意味で、この特性は思考のショートカットとして利用できるのである。脳が利用できる資源は限られているため、単位資源あたりに思考できる量が増えることは非常に歓迎できる。

余談だが、ポアンカレは数学のエッセンスは数学的帰納法にあると言った。数学的帰納法を使うことで無限のステップからなる証明を有限的に記述できるからだ。ポアンカレの主張するところでは、これによってはじめて数学の発展がありうるのである。数学的帰納法は一種の思考のショートカットと言えるかもしれない。

概念と抽象化は根の深いところで関係していると思われる。もしかしたら根本は同じなのかもしれない。ともかく、人間の思考や理論というのは、思考のショートカットを利用し、概念を何層にも積み重ねることによって、複雑化・高度化することが可能になる、と言えるだろう。ソフトウェアは言わずもがな、現代の社会は非常に複雑高度であり、この認知的特性なくしてはそれらを理解し行動につなげることはおよそ不可能だろう。逆に言えば、この特性があってこそ高度なソフトウェアや現代の社会があるのである。

ここでひとつ面白い問題がある。このように高度に発達したソフトウェアや社会を、それらを構成する諸概念をまったく持ち合わせていない人が観察したときに、どのようなことが起こるだろうか。ここではソフトウェアに話を限ろう。もしそのソフトウェアが何らか「筋の通った」やりかたで概念のカスケードを構成しているのなら、利用者は何らかの推測を立てて行動することが可能になるはずだ。逆に、概念のカスケードが何の合理性も持たずに恣意的に構成されていたら、利用者はおそらく何の推測もできずに混乱して終わるだけだろう。関連する用語にメンタルモデルという言葉があるが、メンタルモデルを醸成させる方法に善し悪しがあるのと同様に、概念のカスケードにも何らか筋が通っていることが要求されるだろう。

ソフトウェアと複雑さ

ソフトウェア開発は複雑さとの戦いだと言って差し支えないだろう。ソフトウェアの複雑さには、本質的複雑さと偶有的複雑さがある。前者はソフトウェアによって達成しようとしている物事そのものの複雑さである。簡単に言えば、利用者の判断が必須となる物事、あるいは利用者からは隠すことができない物事に関する複雑さである。後者は、本来であれば(例えば理想的な世界を仮想して)存在するはずのない複雑さである。例えばメモリの容量であったりネットワークの速度に起因する複雑さである。

この本質的複雑さと偶有的複雑さという分類は実はかなり乱暴である。というのもその両者に明確な境界を設定するのが困難だからだ。そもそも理想的な世界など存在しない。これらは相対的な排他的ですらない分類に過ぎない。環境や条件が変われば本質的複雑さが偶有的複雑さに見えることもあるだろうし、あるいはより高次の概念が発明されれば同様のことが起こりうる。その逆も然りだ。

普通、単に「抽象化」と言うとき、本質的複雑さは絶対的に固定のものとして、偶有的複雑さについてのみ専門的に対処することを意味するようだ。もちろん偶有的複雑さの対処だけでも大仕事なのは確かである。例えばガベージコレクションの発明がそうだ。しかしここで言いたいのは、本質的複雑さを抽象化なり概念なりで整理することで偶有的複雑さを解決する糸口が見つかることもある、ということである。時に本質的複雑さに関する抽象化のほうが支配的になることもあるだろう。

発端となった記事の送金の例を考えよう。個人的にはパラメータ化を抽象化とする考え方にあまり同意できない。先の分類で言う本質的複雑さに関する言及がすっぽり抜け落ちているからだ。この例で支配的なのは「口座」と「送金」という本質的複雑さに関わる概念である。「口座」は「独立」で「残高」を持ち、「送金」は「口座」間の「残高」を「融通」する行為であり、普通は「送金」後に「残高」は「マイナス」になってはいけない、等々、説明を突き詰めればいくらでも概念が登場する。これらの概念は、人類が長い時間をかけて発明した概念で、それに従うのはもはや暗黙の了解となっており、実際それに従ったほうがコストが安くつく場合が大半だろう。送金の例で言うと、これらの概念に暗黙のうちに従っているように見えるので、実はほとんどの大きな問題はすでに解けてしまっているのではないだろうか。

パラメータ化により抽象化が瑣末だとは言わないが、これは思考のテクニックではなくプログラミングのテクニックに過ぎないと言って差し支えないだろう。「口座」や「送金」という概念を考えないのであれば、究極的にはすべてパターンの送金をそれぞれ記述しても何ら問題なく、単に無駄にコストがかかっている様子が見えやすいだけだ。逆にパラメータによる抽象化が抽象化らしく見えるのは、すでに何らかの概念に従っている証拠なのだ。

このような考え方に異を唱える人もいるだろう。例えば型システムによる抽象化が可能かどうかという問題がある。個人的にはほとんど不可能だと考えているが、可能だと考える人も存在する。この間には思想的に大きな差異がある。一言で言えば、形式的体系が抽象化を含むか、なのだがちょうど概念と抽象化の区別もあやふやになってきたので、その整理も含めて、このテーゼを否定する理由を次に述べようと思う。

概念と抽象化

概念と抽象化がかなり似た意味を持っていることは先に述べた通りだが、それぞれが対象と行為を表わすこと以外に何か違いがあるかを考えるのは面白い問題だと思う。

一つ考えうるのは、概念に比べて抽象化のほうがより形式的であり最小主義的であり、他方、抽象化に比べて概念は許容的であり動的であろうということである。当然、最終的には両者に優劣はないが、課題へのアプローチの仕方に違いが出てくるだろう。例えば、適当に少し似た動物群を分類するときに、まずそれらを代表する概念を考えて、それでもってそれらの動物群を指すように定義するのか、あるいは共通する性質をきっちり見出して形式的にそれらの動物群(未発見を含む)を定義するのかで、明らかに違いがあるだろう。

オーストラリアで黒い白鳥が見つかったとき、分類学の体系に何が起こったかは知らないが、もしその体系が極めて形式的に定義されていたら、それなりの変更と手間が強いられたのではないかと思う。ソフトウェアにおける黒い白鳥は、一種の洗練のチャンスなのであるが、その存在を無視することが可能なため、意識的にせよ無意識的にせよ無視する方向に傾く可能性があることは指摘しておこう。もちろん現実の要求が強くなるにしたがい無視することはできなくなるので、長期的には洗練され続けることにはなる。しかし、少なくとも短期的には未洗練の形式化を使い続けることになる。

一方、ソフトウェアはきっちり定義しなければそもそも動作するものではないから、概念というあやふやなものでソフトウェアを定義することはできないという主張も筋が通る。先の送金の例ではないが、ソフトウェア以外の世界で使われている概念がそもそも体系として一貫しているかは定かではない。例えばオブジェクト指向プログラミングというのは、概念(というより観念)を強く意識したプログラミング手法だが、長年の検証によりその妥当性を疑問視する声も出て来ている。概念は思考のテクニックであってプログラミングのテクニックたりえない、という証左かもしれない。ともかく、概念とその体系の一貫性や妥当性は保証されているわけではないということ、そしてむしろそれが概念の強みだという理解でよいかもしれない。

要するに、概念と抽象化は状況に応じてバランス良く使おうということだ。概念は大胆に大きな一歩を踏み出す(仮説)のに有用であるが、時に大きな間違いを犯す原因になり、またその体系の妥当性や一貫性を無条件に信用してソフトウェアの定義に導入すると、思わぬ失敗を引き起こす原因になること、そして抽象化は議論を厳密にしたり体系に妥当性や一貫性(形式的体系)を持たせるのには役立つが、例外に対して脆く、それを無視する方向に働く可能性があることを理解しておけばよい。

もちろん抽象化といったときに仮説と形式的体系の適当な混合を指すことがほとんどだろうし、実はそれ以外にその語の真意を表わす方法はないと思われる。というのも、仮説は最終的に形式的に定義されなければならないし、形式的体系を設計する妥当性は信念あるいは仮説に基かざるを得ないからである。つまり「形式的体系が抽象化を含むか」という前節のテーゼは当然ながら否定されるのである。なお議論するにあたっては、その抽象化の形式的度合いが強いか弱いかに注目すれば足りるかもしれない。

あらためて抽象化とは

ここまでの雑多な説明をまとめて抽象化とは何かを考える。まず抽象化が何らかより複雑高度なことを簡単に達成するためにどうしても必要とされることは理解いただけたと思う。また抽象化がソフトウェア設計者のみならず利用者に対しても影響を与えうること、抽象化が偶有的複雑さのみならず本質的複雑さにも関わること、それが時に支配的であることを指摘した。さらに抽象化が仮説と形式的体系の混合のようなものであり、そのバランスが重要であることを指摘した。