読者です 読者をやめる 読者になる 読者になる

おがさわらなるひこのオープンソースとかプログラミングとか印刷技術とか

おがさわらなるひこ @naru0ga が技術系で興味を持ったりなんだりしたことをたまーに書くブログです。最近はてなダイアリー放置しすぎて記事書くたびにはてな記法忘れるのではてなブログに移行しました。

クリエイティブ・コモンズ・ライセンス
特に断りがない場合は、本ブログの筆者によるコンテンツは クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンスの下に提供されています。

デザインパターンと具象と抽象

昨日の話のちょっと続き。

抽象クラスの導出って難しい

私は元々、大学時代は人工知能の研究室にいました。
まあやってた内容は「人工無能との対話によって人間のもつ概念の曖昧さを具体化することができるか」という非常にウサンクサイ内容で、その対象としてソフトウェアの要求把握という題材を採って、知識表現としてのフレーム表現と、当時翻訳が出たランボーのOMTの本:

オブジェクト指向方法論OMT―モデル化と設計

オブジェクト指向方法論OMT―モデル化と設計

なんかを比べたりしてたんですけどね。

で、今の大抵のオブジェクト指向言語って継承概念があるじゃないですか。
でもね、人間って、ものすごく意識しないと、具象とか抽象とかってことを認識できないんですよ、私の感覚からいうと。

知識表現とかオブジェクト指向の例としてよく動物が挙げられますが(鳥は飛べる、鷲も鳩も鳥だから飛べる、けどペンギンは飛べないってのは「飛ぶ」メソッドを上書きして潰しちゃえ、とかね)、これは我々が学校教育で生物の勉強を多少なりともしているからです。だから生物の系統図的なものが頭に入っている。

しかし、そうでないものに対して、常に抽象化してものを考えられるかというと、それは非常に難しい。特にある「モノ」が一個しかない場合はなおさらです。上位下位概念と包含概念とか非常に混同しやすいですしね。
例えばプログラミングの初学者が配列「だけ」を見て、いわゆる「コンテナ」というものの一つであるということを思いつくことは、たぶんムリです。

だから「実世界を、今考えている応用の視点でモデル化して、それをクラスに抽出する」というやり方だと、往々にしてオブジェクト指向のお題目である「クラスの再利用により生産性が上がる」というのがうまくいかないという問題意識があったんではないかなと。

ということで、デザインパターンというのは、「じゃあよくある抽象化を公式としてパターン化しちゃおうよそうだそうだ」ってことなんじゃないかと想像しているのです。よく訓練された人でないと非常に難しい抽象クラスの導入を公式化してやるってことがミソなんではないかと。

そーゆー意味で、オブジェクト指向=継承、という考えをほぐすために、抽象データ型とか、あとJavaScriptみたいなプロトタイプ型オブジェクト指向(親とか子とかいいから、似てる奴からパクッちゃえ)なんかをやっとくといい気がするなぁ。

そして再び継続の話

しつこくてすみませんが、結局「継続」のような概念についても同じなんじゃないかと私は思うんです。
これは言語感覚の話なので、あくまでも私の「感覚」ということでお考えください。

昨日のついったの議論でもあったように、「継続 (continuation)」とは「ある一貫した処理の、途中までやったその続き」というのが一般的な定義です、よね。まぁ Wikipedia の説明でも読んでみてください。昨日ちょっと話に出た、Cのsetjmp()のこともちょっと書いてありますね。例外処理も継続の一種だなんてのは興味深いと思います。

では継続という概念を導入して何が嬉しいか。
それは、「実行状態を保存して続きをやる」ということに名前がつくことがまず一つ。
でもぼくは、それはうれしさも中位なりだと思うんですな。
「ああそれは継続を使うんだね」といったとき、実行状態を「どう」保存するかは各自考えなさい、じゃ、言われたってぜんぜん嬉しくないでしょう? 論文書く人はうれしいかもしれないけどさ。

だから「どう」保存するかも抽象化した、最低でも「パターン」が欲しい。そこまでして、「継続を導入する」とか、そういう用法に重みが出てくると思うんです。だって、それならそのパターンを使うってことで、やることが明確になるから。

そしてどのようなプロセスであっても抽象的に「ここまでやった、残りはあとで」ってことをしたければ、「実装としては」実行コンテクストを保存するしかないじゃないですか。だって、どんな処理かわかんないんだから。そしてそれは多くの言語で実現がとても困難、というのは先に述べたとおり。

ただし、「どんな処理でも、っていうのはムリだけど、こんな処理に限定して、っていうことなら、こういうクラス/関数/なんとかかんとか、を書けば、ある程度抽象化できるよ」ってのはあるでしょうね。それを綺麗にパターン化できるなら、意味があるかなと思う。ただし私は頭のいい方ではないので、これについては具体例が思いつかない。

あんままとまってないけどまとめると、

  • 定義として「継続ってのはある処理のある時点からの続き」ってのはある。
  • けどそれを「実装する文脈で」使ってもうれしくもなんともない。
  • 実装する文脈でうれしいというには、抽象概念に対応した具体的な何かが必要。
    • 「具体的な何か」として実装ということなら、実行コンテクストを保存するよりないし、それは多くの言語で困難。
    • 「具体的な何か」として、汎用性をある程度捨ててもよければデザインパターン的なもので対応できるかもだけど例は思いつきませんゴメンナサイ。

つまり、なんですな、「なんのために」「なにを」抽象化するかってこと。
結局具象化したものを綺麗に便利に使いたいから抽象化するんでしょうと。

コード書くのではなくて、論文を書くんであれば別でしょうけど……デザインパターンってコード書くための生活の知恵なので、その勉強をするというコンテクストであれば、「継続」も生活の知恵になってくれなきゃ概念を導入する意味がない、というふうに、私は感じています。