viscuit
https://gyazo.com/0ea417a60b012bfc584fd8239aea01f6
オブジェクト指向プログラミングを神格化するような記事が流れてきたので,僕が知っている問題點について書いてみたいと思います.僕がまだ學生だったころは,オブジェクト指向の評價もまだそれほど定まっていなくて,オブジェクト指向の次はどんなパラダイムが出てくるかとか普通に學生レベルで議論していたものですが,ここまで強大になってしまふとそれを打ち負かさうなんて氣にはならないのでせうか.僕にはオブジェクト指向が普遍的な眞理という感じは全然しなくて,ここまで使はれてる理由は,現實的なテクノロジーで大きなシステムを作らなければならない必要性のはうを優先した結果であると認識しています.オブジェクト指向がその後の 25 年ほどもずっと安定してその地位を保てるほど素晴らしいものとは思へないのです.
以下で上げる問題點は,個別に解決してゐる硏究はあったりしますし,僕も論文を書いたりしましたけど,實際の言語に導入されていなければあまり意味がないので,問題點として指摘させていただきました.論文じゃないので,輕い氣持ちで読んでいただければと思います.
1)メッセージの流れが見えない
オブジェクト指向においてメッセージのやり取りほど重要なものはないのに,そのやり取りの樣子がプログラム上で表現できていません.メッセージの送信は,繰り返しや條件分岐などの制御文によって作られた函數呼び出しの副作用として閒接的に表現されます.一方受信の方はもっと見えなくて,例えばその時のオブジェクトの內部狀態によって受信できるメッセージの種類が變わるはずなのに,そういった制御や抽象化ができません.最初に初期化のメッセージを受信した後,處理のメッセージをいくつか受信して,終了のメッセージを受信する,といったプロトコル的な記述もできません.
2)オブジェクトのつながり具合が手續きでしか表現できない
次に大事なのがオブジェクトのつながり具合です.たとえばMVCという3つのオブジェクトの集まりで一つの部品を作るような場合があります.プログラムは,M,V,Cそれぞれが同じ相手とつながっていることが前提でつくられます(たとえば,Mが知っているVと,Cが知っているVは同じものである,といったことです).しかし,このつながり具合が正しいかどうかを保證する方法がありません.木構造をオブジェクトで作るとき,自分の子供は全員自分を親として見ているか.こういったつながりを手續きで頑張って作るので,閒違えが入る可能性があります.閒違えをできるだけ入らないようにするために,オブジェクトの外側からは內側を觸れないようにカプセル化しますが,そういう制約はオブジェクト指向自身が自由度が高すぎる,逆に言うと何も保證しない貧弱であるから必要なのです.
3)ユーザレベルでの部品化再利用に全然なっていない
僕が素晴らしいプログラムの部品化再利用の例だと思っているのがUNIXのパイプラインです.これが通じる人はどれくらいゐるのかな.コマンドの出力が次のコマンドの入力になるようにパイプでつないで表現するものです.パイプが人閒にとってすごく使いやすい理由は,そこを流れるデータが人閒に見える形式だったからです.見えるから次のコマンドにどんな處理をさせればよいか考えやすくなります.何か動きがおかしければ,途中に流れている文字列を見ればわかります.典型的な入力データをエディタで作ってもよいですし,途中の處理が特殊すぎてわざわざプログラムで處理しなくてもよいような場合,人閒がエディタ上で手作業で編緝してもよいわけです.テキストデータという共通のデータ形式の上で人閒とコンピュータが協調して問題を解いていたという感覺がありました.
こんな素晴らしい仕掛けが使はれた時代はそんなにコンピュータが速かったわけではありません.それでもバイナリーではなくテキストの10進表記で數を表すという,實に無駄な方法が人閒の利便性を優先して使はれていたということに敬意を表します.
1 次元にコマンドを竝べて處理を順に行ふやうな單純な處理だけですむ時代は終はりました.パイプに代わるもっと複雜なコマンドの組み合はせ方を發明しなければなりません.パイプは一方向の情報の流れでしたが,情報は雙方向の流れを許すべきです.
僕はUNIXにX-Windowというウインドウシステムが入ってきたとき,次世代のパイプが發明されるのかとワクワクしてましたが,結局まだ誰もそれを發明できていません(僕が知らないだけであるのかもしれません).部品化はオブジェクト指向にとってかわられ,プログラムの中は閉ざされ,人閒は遠ざけられました.
北大の田中先生のIntelligentPadにその可能性を感じましたが,結局はオブジェクトの合成という非常に難しい問題がその前に立ちはだかりました.
そうこうしているうちに,WWWの大爆發が起こって全部吹っ飛びました.
4)知識表現が手續き側に偏っている
プログラミングという處理っぽい呼び方ではなく,もう少し廣い意味を込めて知識表現と呼ぶことにします.プログラムはもちろん知識表現の一部です.たとえば,EXCELの表も知識表現ですし,構造をもったデータは知識表現です.オブジェクト指向の何が悲しいかというと,構造をもったデータを直接作り出すことはできないということです.手續きを使って變換するしかありません.たとえばLispではコンピュータが處理するデータ構造を人閒が直接入力することができます.そういう人閒とコンピュータの仲の良い關係がオブジェクト指向では消えてしまってます. 5)オブジェクト指向は人閒をだましている
オブジェクト指向で作られた典型的なグラフィカルなプログラムを考えましょう.オブジェクトには內部狀態があります.その內部狀態を更新させることが唯一の計算です.その內部狀態を人閒にみせるためのプログラムと,人閒が見ているもの(畫面)に對するマウスやタッチの操作を解釋して內部狀態を更新するためのプログラムがあります.これは上の例ででてきたMVCということなんですが.だましているといったのは,Mは內部に存在しますけれども,Vがどう作られたかで見え方が違ってきます.同じ見え方でもMの中身が違っていたり,同じ中身でも見え方が違っていたり,ということが平氣で起きます.眞逆は Lisp です.Lisp はコンピュータが見ているメモリーの構造と人閒が見てゐるS式とが1對1の關係になるので,つまり人閒とコンピュータが同じものを見ているという安心感があります.オブジェクト指向はコンピュータと人閒が同じものを見ている感がしません.コンピュータがすごく頑張って人閒にすごいものを見せている(もしくはだましている)という感じです. かうなっちゃった理由は,コンピュータに課せられた役割が,これまでプログラムを作る人と使ふ人とが一體となってゐた時代から,作る人と使ふ人とが明確に分かれた時代に變はってきたといふことなのかもしれません.UNIXのテキストは人閒にわかりやすいといっても,ビットマップのテキストよりは見榮えがしないわけで,作る人と使ふ人が一緒なら我慢もできましょうが.逆に,使ふだけの人にとっては,上手にだましてもらったはうがいいわけですし,よりかっこよくだました方がお金が儲かるという事情もあったのでせう.
6)オブジェクト指向は貧乏
オブジェクト指向が活躍した時代はメモリーが非常に少なくどう節約するかが重要でした.なのでよく使われていた例は,列というものがあって,その列をどのやうに扱ひたいかによって實行の效率が變はるので,使用法に適した實裝を選んで效率をよくすることができる.しかしアルゴリズムはそのデータ構造の影響を受けないように計算方法だけ書けばよい.そんなことが言われていた時代でした.つまり,一度書いたアルゴリズムはいろんなデータ構造に對して,效率の良い實行ができるというものです.
しかし今は,メモリーもふんだんにあって實行速度の差もそれほど重要ではなくなってきたので,そんな實裝方法に依存しないアルゴリズムといふ貧乏なことを言わなくてもよくなりました.万能なデータ構造を一つ決めて,アルゴリズムは全部その構造に對して作ってしまえばよいのです.Lisp みたいなものです.ただし,Lisp の時代から何が變はったかといふと,扱ふデータが木構造のように單純ではなく,グラフ構造になったこと.一つのスレッドではなくマルチスレッドでかつ分散になったこと.オブジェクトが複雜に參照しあっているようなグラフ構造を Lisp の S 式のやうなシンプルで汎用性のある記法で記述しなければならないといふことです.なので S 式的な今風の擴張が求められてゐます. 7)關係を記述できない
メッセージは單項演算なので,複數のオブジェクト閒の關係を表現するのが苦手です.ある一つのオブジェクトに,起きろ,步け,といった命令をするだけなら簡單です.それに對して,二つのオブジェクトが關係する命令,たとえば二人に對して,ぶつかれ,ならべ,という命令が苦手です.通常のオブジェクト指向では,關係するオブジェクトのどれか一つを特別に選んで,それに對するメッセージとして表現します.他のオブジェクトはそのメッセージの引數として渡されます.2)で言ったようなつながり具合を表現したければ,メッセージの受信側に選ばれたオブジェクトが責任をもって引數で渡されたほかのオブジェクトどうしをつながなければなりません.
Prologは關係を表現できます.というか關係しか表現できません.たとえば,A+B=Cという式があったとします.普通の言語ではA+Bの計算をして,Cのメモリーにその値を書き込むという解釋をします.AとBの値が決まっていてCは未定義だったり,Cの新しい値としてかういふ計算をしました.それに對して,ここで表現した式は計算の方法ではなくあくまでも式というか變數同士の數學的な關係を表していると解釋できます,たとえばこの式があったとき,Prologでは「Bが20,Cが50のときAは何でしょう」といふ聞き方にもこたへることができるのです. 計算の方向まであとで決められるくらいの自由度はともかく,オブジェクト指向がメッセージのやりとりにこだわっていると,關係を表現するのがすごく大變といふことはわかっていただけたでしょうか.
オブジェクト指向の問題點のうち,ごく一部はビスケットの設計方針に影響を與へてゐます.たとえば,コンピュータが裏で人閒のために頑張るといふのではなく,コンピュータと人閒が同じものを見てゐる感といふのを大事にしてゐる部分などですが.人閒とコンピュータの關係がどうあってほしいかといった思ひも込められてゐます.
ビスケットの開發思想といいますか,哲學のようなものの一つに「見えるものがすべて」という考へ方があります.Scott Kimさんの論文VIEWPOINT の中でビジビリティ(Visibility)として定義されてゐます.人閒とコンピュータは同じ畫面をみて協調して動くべきである,という考へ方です.
たとえば畫面に「+」という文字がかかれています.これは全角のプラスという文字です.見えているのは2本の直線が垂直に交差したものですが,文字です.それとは別に,畫面に2本の直線で+の文字とまったく同じに見えるように描畫したとします.コンピュータにとってはそれは文字ではなくて2本の直線です.同じように見えても,コンピュータの內部の扱いが違うのです.いまのコンピュータの發展の歷史を知っている人ならば,これはまったく當たり前のことで「それがどうした」ということだと思ひます.
ところがビジビリティの考へ方では人閒が見えているものとコンピュータが見えているものは同じであるべきといふことです.2本の直線で十字を作ったとしても,コンピュータには文字のプラスとしても認識して動いて欲しいということになります.
私が昔作ったデモシステム(硏究用のちょろっと動くもの)では,キーボードから「はらた」と入力します.その後,マウスで「た」の右上に2つ點を書きます.そうするとそれは文字の「はらだ」として認識してくれる,というものでした.處理としては每囘畫面に文字のピクセルとの比較をするというとても重いものでした.
そもそも紙の上にペンで何かを書く時に,定規を使おうがフリーハンドで書こうが,文字だったり線だったりという秘密の情報をインクが持っているなんて變な話で.紙に書かれたものはそこに表現されている情報がすべてと考へるべきです.
それが,コンピュータの畫面に關しては,どういふ方法でその畫像が作られたのか,そしてコンピュータだけが知っている內部狀態と,畫面で見えている情報とがまったく無關係であるといふことが大手をふって威張ってます.
以前のブログでもオブジェクト指向の問題點を書きました.その中の「5)オブジェクト指向は人閒を騙している」というのがその指摘です.內部狀態とはまったく獨立に人閒に見せる畫像を生成させてます.見え方と內部狀態とが一致しているのはたまたまそういうプログラムを書いたからで,一致させないようにプログラムを書くこともできます.
ただし,考へ方としては,ビジビリティは非常に優れてゐると思うのですが,實際のコンピュータの畫面は1000×1000位の色のついた點でしかありませんから,なにかの工夫をしなければほとんど何もできません.そこにどんな工夫をすればビジビリティを保ちながらまともに使へるシステムが作れるのか.そこが難しい問題です.
隱蔽しない。隱蔽されたものは異なる背景で組み合はせられず、複雜さの元と成るClojure.icon