先日、松岡正剛著『知の編集工学』を読みました。
そこでプログラマーにはお馴染み「オブジェクト指向プログラミング」が言及されていましたが、具体的なコードの例がなく(そりゃそう)分かりづらいと感じた部分がありました。
そこで、今回の記事ではオブジェクト指向プログラミングの基礎的な概念とその応用可能性について、『知の編集工学』をベースにPythonのコードを用いて解説します。
なぜオブジェクト指向プログラミングなのか?
Macintoshなど現代のコンピュータに不足している点として、松岡正剛(1996)は「物語に基づく情報の記述」を挙げています。
物語には7種類ほどの原型が存在し、古今東西の物語は原型に基づいて展開されています。物語とは必ずしも文学作品のみを指すのではなく、『小学生の日記からビジネスマンの営業企画まで』(松岡 1996: 283)日常的に多用されていると言えます。
一方、このような『物語的構造感覚』(松岡 1996: 283)は、現代のコンピュータシステムにうまく組み込まれていません。
そこで、松岡は物語のコンピュータリゼーションにあたり、物語を『5W1Hをくりかえす情報の連鎖』(松岡 1996: 283)とし、その出来事の連鎖に関するモデルの制作、およびこのモデルに従った情報編集を提唱しました。
しかし、物語のコンピュータモデリングには、物語の進行途中では本筋以外にも多数の脇道が併存するにも関わらずコンピュータがこれを表現できないという課題が存在します。
この課題の解決策としてプログラムが処理できる方法での情報の並べ替えなどが挙げられますが、この方法でも物語の電子化には遙かに隔たりがあります。新たな解決策として、オブジェクト指向プログラミングが提案されました。
オブジェクト指向プログラミングの基礎
※ここからの内容は一部ChatGPTの出力を参考に執筆いたしました。
オブジェクト指向プログラミングにおける重要な概念として、クラス/インスタンスとポリモーフィズムについておさらいします。これらの用語に詳しい方も、今回の記事独自の用法もあるかと思いますので一読することをおすすめします。
クラス/インスタンス
クラスとインスタンスについての説明としてよくあるのは、「クラスとはオブジェクトの設計図、インスタンスは設計図から作られた実体」というものです。
物語の編集におけるクラスとインスタンスの定義も上記とそれほど変わりません。『知の編集工学』において、クラスとインスタンスは以下のように定義されます。
クラスは「それ以上分解しないほうがよいとおもわれる内部を持つ意味単位」(情報単位)のことをさし、インスタンスは「クラスが記述されたとたんに例示できる情報」のことをさす。(松岡 1996: 292)
ルイス・キャロル(1832)著『不思議の国のアリス』の登場人物を例に、クラスの概念を考えてみます。
# クラス(型、設計図)
class Character:
def __init__(self, name, age):
self.name = name
self.age = age
def self_introduction(self):
print(f"わたしは{self.age}歳です")
# インスタンス(具体的なかたまり)
Arice = Character("アリス", "7")
Arice.self_introduction()
# 出力:わたしは7歳です
ここでCharacterというクラスを作ると、いちいちデータをバラバラに扱わずに「登場人物」というひとまとまりの概念として扱えます。
『不思議の国のアリス』では他にも白うさぎや女王様などの登場人物がいますが、クラスを作ることで、わざわざArice、White_rabbit、Queenそれぞれについて関数などを作る必要がなくなります。
ちなみに『知の編集工学』では、クラスは「型=エディティング・モデル」とも呼ばれています。人がコミュニケーションする時には、このエディティング・モデルをやり取りしている、と言えるとのこと(松岡 1996: 116)。
(クラス=エディティング・モデルをやり取りすると言うよりも、クラスから派生したインスタンスをやり取りすると考えた方が、個人的には納得感があるのですが…)
ポリモーフィズム
クラスを作るもう一つの利点として、「単一のクラスから生成したインスタンスは共通の関数でまとめて操作できる」ということが挙げられます。この性質は、ポリモーフィズムと呼ばれています。
松岡(1996)はポリモーフィズムという単語こそ使っていませんが、代わりにマスキングという言葉を使い、
あるモジュールの内部状態が、それを活用する別のモジュールから遮蔽されるようなダイナミズムをとるようにしておく(松岡 1996: 290)
と説明しています。
同じ操作を、「複数のインスタンスを共通の関数でまとめて操作する」という文章では関数を付与するプログラマー(私たち)の視点から、「あるモジュールの内部状態を他のモジュールから見えないようにマスキングする」という文章では関数を付与されるインスタンスの視点から表現しています。
ポリモーフィズムについて、再び『不思議の国のアリス』を例に考えてみます。
# クラス(型、設計図)
class Character:
def __init__(self):
pass
# トランプの5と7
class Trump_5_7(Character):
def asked(self):
return "押し黙って2をにらむ。"
# トランプの2
class Trump_2(Character):
def asked(self):
return "小声でこう言った:「その何だ、実はさ、ほら、じょうちゃん、本当はこいつ赤いバラの木のはずだったんだけど、手ちがいでオレら白いのを植えちまってさ…」"
# 出典:ルイス・キャロル著、大久保ゆう訳『アリスはふしぎの国で』, https://www.aozora.gr.jp/cards/001393/files/57320_57183.html
def asked_by_alice(Trump):
return Trump.asked() # この関数だけでトランプ2、5、7の挙動が記述できる
# アリスはトランプたちに、なぜバラを塗っているのか尋ねた。
print("トランプの5と7は", asked_by_alice(Trump_5_7()))
print("トランプの2は", asked_by_alice(Trump_2()))
# 出力:
# トランプの5と7は 押し黙って2をにらむ。
# トランプの2は 小声でこう言った:「その何だ、実はさ、ほら、じょうちゃん、本当はこいつ赤いバラの木のはずだったんだけど、手ちがいでオレら白いのを植えちまってさ…」
「どうしてバラを塗っているの?」というアリスの問いかけに対する返答を、asked_by_alice()という関数でまとめて出力できます。
また、この「多様なインスタンスを共通の関数で操作できる」という性質は、松岡(1996)がヴィトゲンシュタイン、フレーゲ、西田を挙げて説明した述語の一般性に繋がるものがあります。
「〜である、という言語において人間は一致する。それは意見の一致ではなく、生活様式の一致なのである。」
(ヴィトゲンシュタインの言葉)(松岡 1996: 266)
「判断というものは、じつは主語が述語を包摂することなのだ」(西田の言葉)(松岡 1996: 268)
オブジェクト指向プログラミングで物語を編集する
松岡(1996)は、オブジェクト指向プログラミングを用いて物語を記述する上で、上記のクラス/インスタンス、マスキング(ポリモーフィズム)に加えて、情報の関係付けが重要であるとしています。
また、具体的な関係として、以下の3種類の『関係線(link)』を挙げています。
Navigational Link……移動リンク、ズームリンク、パンリンク、マスクリンク
Analogical Link……索引リンク、所属リンク、属性リンク、含意リンク、実行リンク
Editorial Link……階層リンク、拡張リンク、視点リンク、背景リンク、交換リンク、報酬リンク、条件リンク (松岡 1996: 292)
リンクの導入によって、
- Navigational Link → 物語の進行・視点移動
- Analogical Link → 登場人物や出来事の「たとえ・メタファー・属性」
- Editorial Link → 物語を編集するルールや視点の切り替え
を表現できます。
また、登場人物の過去や所属先、行動の持つ意味といった「脇道」も、リンクとして保存できるわけです。
では、先述のクラスにリンクを活用すると、どのように物語が描写されるのか、プログラムの例を見てみましょう。
# 登場人物の設計図
class Character:
def __init__(self, name, role):
self.name = name
self.role = role
# リンクの設計図
class Link:
def __init__(self, type_, source, target, description):
self.type_ = type_ # 今回は簡単に、Navigational, Analogical, Editorialの3種で記述
self.source = source # 登場人物1
self.target = target # 登場人物2
self.description = description # リンクの内容を説明
# 登場人物
alice = Character("アリス", "主人公")
queen = Character("ハートの女王", "敵対者")
# リンク例
link1 = Link("Navigational", alice, queen, "アリスが女王の城に移動する") # 場面の転換
link2 = Link("Analogical", alice, queen, "女王はアリスの恐怖心の象徴") # 比喩表現
link3 = Link("Editorial", alice, queen, "女王はアリスに苛立っている") # 視点の転換
for link in [link1, link2, link3]:
print(f"{link.type_}: {link.source.name} <-> {link.target.name} ({link.description})")
# 出力
# Navigational: アリス <-> ハートの女王 (アリスが女王の城に移動する)
# Analogical: アリス <-> ハートの女王 (女王はアリスの恐怖心の象徴)
# Editorial: アリス <-> ハートの女王 (女王はアリスに苛立っている)
上記のコードではリンクを全てテキストで表示していますが、多様なリンクやインスタンス同士の繋がりを視覚的に表現するツールがあれば、物語の解析が一層充実しそうです。
終わりに
今回の記事では、オブジェクト指向プログラミングの基礎的概念を『知の編集工学』の内容と突き合わせながら紹介するとともに、オブジェクト指向プログラミングとリンクの併用による物語編集の例を示しました。
編集工学において、「物語」はオブジェクト指向プログラミング以外の幅広い文脈で有用性が主張されているので、それらについても別記事で解説していく所存です。
参考文献
松岡正剛(1996)『知の編集工学』朝日新聞社