このブログは、旧・はてなダイアリー「檜山正幸のキマイラ飼育記 メモ編」(http://d.hatena.ne.jp/m-hiyama-memo/)のデータを移行・保存したものであり、今後(2019年1月以降)更新の予定はありません。

今後の更新は、新しいブログ http://m-hiyama-memo.hatenablog.com/ で行います。

ハイパーオブジェクト

ハイパーオブジェクトとは、しみじみ難しい概念だ。オブジェクト指向パラダイムでも関数型パラダイムでも、うまく説明できない。むしろ、そういった既存のパラダイムは理解や解釈の邪魔になるだけだ。

ハイパーオブジェクトはリモートメソッド(ハイパーリンク)を持ったオブジェクトなのは事実だ。だが:

  1. ハイパーオブジェクトはクラスを持たない。(クラス概念がない。)
  2. ハイパーオブジェクトはコンストラクタを持たない。
  3. それにも関わらず、ハイパーオブジェクトはインターフェイス(指標)を持つ。
  4. ハイパーオブジェクトはデータオブジェクトでもあり、複雑なデータ構造を持つ(かも知れない)。
  5. ハイパーオブジェクトは状態点(状態空間の点=オカレンス)となる。

この奇妙な状況を理解するには、初期のC++のような原初的なオブジェクト指向もどきに遡って考えるとよいように思う。

C++、というより、Cで自作オブジェクト指向もどきシステムを作ることを考える。インスタンスオブジェクトとは構造体に過ぎない。クラスの物理的実体は、関数ポインタを並べた配列だ。インスタンスはどれかのクラスに所属するので、構造体には「クラス=ディスパッチテーブル」の先頭アドレス(ポインタ)を入れておく -- classと書いたフィールド(構造体メンバー)がそれだ。

データメンバー以外に、構造体にはメソッドが含まれる。メソッドは、ディスパッチテーブルのインデックス(先頭アドレスからのオフセット)で表すとする。例えば、番号2はdoThis関数を(間接的に)示す。番号3は、doThat関数を示す。

メソッド呼び出しは、構造体objのclassフィールドが指すディスパッチテーブル(のアドレス)obj.classに「メソッドの番号=配列インデックス=オフセット値」でアクセスする。obj.class[obj.doThis] でdoThisが得られる。thisを第一引数に入れるなら obj.class[obj.doThis](obj, arg) のようになる。

Webサイトは、原初的オブジェクト指向に少し似ている。

クライアント側にロードされたページにはデータとリモートメソッドが含まれる。出自となったサイトへのポインタ(URL)はページ自体に埋め込まれてなくてもブラウザは把握している(originのリンク)。ページに含まれるアンカーが相対URL(パス)なら、サイト内での位置を示していることになる。サイトは、一種のディスパッチテーブルと見なせなくもない。ディスパッチのキーは番号ではなくてパス名となる。

WebアプリケーションをRPCベースのハイパーオブジェクトで考えた場合、実際はもっと複雑になる。

まず、ハイパーオブジェクトは複雑な階層的なデータ構造となり得る。リモートメソッド(へのトリガー)は、複雑なデータ構造のなかに散りばめられている。単にフラットにメソッドが並んでいるわけではない。foo, bar, bazがトリガーだとして、それらが指す先が単一のサイトとは限らない。多重継承やマルチメソッドとも違って、ひとつのハイパーオブジェクトに色々な場所に散在するリモートメソッドを混ぜていいのだ。

オブジェクト指向では、「データ構造」と「手続きモジュール」と「メモリアロケーションと初期化」を、クラス概念によってまとめ上げた。ハイパーオブジェクトでは、これらがまとまってない。バランバランだ。データ構造と手続きモジュールの構造は無関係で、異なる編成がなされている。明白なコンストラクタはなく、すべてのメソッドがコンストラクタと言えなくもない。

このような状況でも、RPC、IDL、IDLコンパイラの概念は相変わらず有効だ。他の解釈や手法は破綻していて適用できない。