Janusについて雑多なこと

檜山正幸 (HIYAMA Masayuki)
Wed Jan 26 2005:start
Wed Jan 26 2005:prefinal

Janusについて書いた2つの記事をインフォーマルに補足するために、 雑多なことをオシャベリする。

目次

1. はじめに

文章(書かれたもの)によるコミュニケーションでは、誤解・曲解は避けが たい。インフォーマルな会話(つまり、雑談ですな)や、ホワイトボードに描 いた殴りがき、あるいは、ちょっとした仕草などに含まれる情報はけっこう膨 大なものである。明確に言語化されえる情報にしても、口頭と文書では情報の 質・量が異なる。例えば、ある人が 「それは××だと思うよ。あっ、ゴメン、○○が正しいな、ウン」と語ったと しよう。それを文章にすると、××の部分は書かないで、「それは○○である」 と書くだろう。だが、彼が最初は「××だ」と述べたという事実から、彼の発想 や考え方がうかがえるってこともある。

文章の形で提示されるのは、アイディアや意見の断片であり、その総体では ない。文書としての完成度が高ければそれだけ、「××だ、いや違う」「△△ かもしれない、どうも自信がないが…」といった、思考の経緯/表現のニュア ンスは削り落とされる。つまり、よくまとまった明確な結論というのも断 片なのだ。粗雑に散らかされた断片でも、洗練された断片でも、所詮は断片、 そこからもとの意図をくみ取れる保証はない。むしろ、たいていは誤解や曲解 につながる。

だが、誤解や曲解が一概に悪いわけではない。ある人が言ったり書いたりし たものから、話者/著者がまったく意図してないメッセージを受け取る人もいる/場 合もある。そしてそれが、たいへんに建設的なこともある。まれにだが、僕が 「こうしたらいいと思うよ」とたいした確信もなく言ったことを真に受けて、 なかなか素晴らしいプログラムが出来あがることがある。これなどは、「良い 誤解・曲解」ということになる。

前置きが長くなりすぎた。この記事の目的を述べよう。 「Janus(ヤヌス)の紹介 -- stdin/stdoutからの入門」「Janus(ヤヌス)の紹介 2 -- フィルターからコンポ ネントへ」という2つの記事を書いた。自分で読み返してみると、「これは 誤読されそうだ」という気がした。今述べたように、もとより誤解・曲解は覚 悟の上だが、誤読の原因が「記事があまりにも断片的過ぎる」ことであるなら、別な 断片を追加することによって情報量が増え、幾分かは改善されるかもしれない。

Webサイト上の記事をコミュニケーション手段に選んだからには、 「インフォーマルな会話、ホワイトボードに描いた殴りがき、ちょっとした仕 草」などの伝達チャネルは一切使えない(*注1)。となれば、断片の総量を増や すしかない。完成度や洗練度にとらわれず、「××だ、いや違う」「△△かも しれない、どうも自信がないが…」といった経緯も残るようにしたい。

注1

ホワイトボードに描いた殴りがきに非常に近い画像を図に使っているけどね (苦笑)

とまあ、そういう事情で、「Janusの紹介」を補足する雑談をゴチャゴチャ・ ダラダラとします。

2. Janusは「コンポネント・アーキテクチャ」なのか?

Janusコンポネント・アーキテクチャは、COMやJavaBeansのような既存のコン ポネント・アーキテクチャの類似物や代替案というわけではない。だったら、 「コンポネント」とか「アーキテクチャ」って言葉を使わなければよさそうだ が、代わりの言葉も思いつかない。

僕は(たぶん多くの人が)、よく定義された(well-definedな)ソフトウェア 的な“かたまり”、”部品”をコンポネントと呼んでいる。システム、プロセ ス、オブジェクト、モジュールと呼んでも別にかまわない。が、それぞれに言 葉としての難点がある。

それで結局、コンポネントと呼ぶことにしたのだ。

「アーキテクチャ」もあまりにも漠然としている言葉だ。普通、アーキテク チャというと、それに基づいた実装を想定するのだろう。が、僕は、Janusの 具体的実装を期待しているわけではない(*注2)。実装の基準になるほどの精密 な仕様を作るのは大変だ(誰かやってくれるならいいけど)。僕が言いたいこ と/望んでいることは、「明確にできることは明確に記述したい、計算できる ことは計算で済ましたい」ということだ。そのために、Janusで提示している 発想や枠組みが役立つだろうと期待している。

注2

実装は欲しいが、相互運用性や再利用性を高める基盤のようなものは期待し てない。むしろ、特殊特定なアプリケーションが欲しいのだ。

理念的/概念的な傾向があるのだから、方法論(メソドロジー)と呼べばい いのだろうか。それも抵抗がある。方法論と呼べるほどに整備された体系は ない。むしろJanusは、今後、方法論を考えていく上での素材や道具として使 いたい。そのJanusでさえ未完成ではあるけど。

3. Janusのお作法

Janusコンポネントを理念的/概念的なレベルで解釈すれば、相当に守備範囲 は広い。これは、そう思いたいなら、なんでもJanusコンポネントだと思える ことであり、そんな希薄な概念に意味があるか?という議論を引き起こすだろ う。

理念的/概念的なレベルのJanusコンポネントは、希薄でゆるい。が、コンポ ネント構成(composition、connection)は制限がきついし、この構成法に適 合できるという条件を課すと、実はさほどゆるいとも言えない。つまり、具体 的/実装的なレベルでは、それなりの基盤と規約を要求されるだろう。

Janusで許しているコンポネント構成演算は、直列結合、並列結合、フィード バック(トレース)の3つだけだ。それ以外に、コンポネント構成に便利に使 える接合用コンポネントを“ジャンクション”として準備しておくことができ る。(典型的なジャンクションについては、ETBダイア グラムを参照。)ジャンクションは特別なものではない。ジャンクション もコンポネントの一種に過ぎない(*注3)

注3

ジャンクションの機能/振る舞いは前もって記述されてなくてはならない。 その機能/振る舞いは等式で記述されることが多い。この等式群が、推論・計 算の機構に作り付けになる点では特殊ともいえる。

「Janus(ヤヌス)の紹介 2」では、極性と双方向 性(対称性)を導入した。これがあると、コンポネントをひっくり返す演算が 導入できる。その演算は、双対、随伴、転置、反転、対合など、いろいろな呼 び方があるが、実際の演算は1つだ。このひっくり返し演算を入れても、許さ れる構成演算は4つしかない。

僕は、「よく定義された構成要素に対して、少数の構成演算だけを使え」と 言いたい -- この主張は、大昔の「構造化プログラミング」の主張そのもので ある。全然新しくない。そもそも僕は、新しいことを考え出す能力はない。だ から、昔から知られていることを“再利用”している。

「構造化プログラミング」は、「プログラムの構成に対して、あんまり勝手 なことをするな」と、お作法を提唱したともいえる。Janusも、「コンポネント の構成に対して、あんまり勝手なことをするな」と主張しているのだ。

4. スパゲッティ問題

なんで、「あんまり勝手なことをするな」と呼びかけるかというと、それは、 勝手気ままなことを続けるとグチャグチャになってしまうからですよ。

最近は、良いコーディングをサポートしてくれるツールもあるし、厳しくコー ディング教育をしている組織もある。それでコード可読性は上がってけっこう なことだが、「システム全体はどういう構造なのかな」と知りたくてもさっぱ り可読(つうか可理解)じゃなかったりする。

「構造化プログラミング」の時代に、gotoを使いまくって制御構造がグチャ グチャになったプログラムをスパゲッティ・プログラムとかスパゲッティ・コー ドとか揶揄したが、今なら、スパゲッティ設計とかスパゲッティUMLってとこ ろだろうか。

Janusは、もともとの発想がパイプ&フィルターだから、入出力を持つ(当然 に方向性を持つ)コンポネントのパイプラインしか作れない。文字通りの1次 元パイプラインではさすがに制限がきつすぎるから、拡張はしている。並列結 合でコンポネントを(入出力と無関係に)並べることもできるし、フィードバッ ク(トレース)を使ってループを作ることもできる。(フィードバック、トレー スについては、現時点ではまだ説明してないが。)コンポネントは、一定の向 きに沿って組み合わされる(パイピング、ワイヤリングされる)が、コンポネ ント間の通信は双方向が許される。つまり、Janusの複合コンポネントとは、 高次元化され、ループを許し、双方向化されたパイプラインである。

コンポネントをノードとして、通信(メソッド呼び出し、データストリーム、 イベント/メッセージ・パッシングなど)の経路を有向辺とするグラフを考える (*注4)。このようなグラフが複合コンポネントの構造を表すと考えてよいだろ う。Janusパイプラインは、任意のグラフを表せるわけではない。 だから、表現力は落ちている。表現力を犠牲にして、秩序と計算可能性を手に 入れたいのだ。表現力の不足が問題になることがあるかもしれないが、スパゲッ ティ・グラフまで表現できるほどの余計なパワーは必要ない。

注4

Janusでは、「インターフェースがノード、コンポネントが辺」になるような グラフを考えたほうが自然なときもある。

5. 双面神の右と左

Janusコンポネントでは、入出力仕様の明確化を絶対的に要求している。自然 で直感的な意味がないときでも、入力と出力を完全に切り分けなくてはならな い。そして、2つのコンポネントA、Bの直列結合可能性を、 「Aの出力仕様が、Bの入力仕様と完全に一致する(極性があるときは、極性は 互いに逆)」ときに限定している。これは、不便なこともあるのは事実だ。だ がここでも、多少の不便さを我慢して得られるものがあるから、このような方 針にしてる。

極性と双方向性が入っていると、Janusコンポネントの入力と出力をひっくり返す のは容易だ。ひっくり返しはコンポネント実装に手を加えずにできるし、ひっ くり返すことにソフトウェア的な意味もある。このひっくり返しは、 双面神に「回れ右」(*注5)してもらうことになる。ひっ くり返してもちゃんと機能するから「対称性を持つ」ということになる。

注5

「回れ右」って、180度の回転のことだよね? 僕は、子供の頃(いまでもか)、 「回れ右」と「右向け右」の区別がよく分からなかった。

だが、「ひっくり返し」や「対称性」を議論するには、前もってひっくり返っ ていない状態が指定されてないと話の土台がない。双面神の首から上だけ 見てると、彼(彼女かも)が、コッチを向いているのかムコウを向いているか 分からない。別な言い方をすると、お腹を向けているか背中を向けているか区 別がつかないのだ。しかし実際には、首の下に胴体があるから、お腹と背中の 区別がある。右と左の区別もある -- これで、「右の顔と左の顔を入れ替える」 という言明が意味を持つ。

つまり、「ひっくり返してもOK」といった対称性に関する主張をするには、 ひっくり返す前と後を記述できなくてはならない。前もって、「右と左」 「表と裏」「入り口と出口」といった概念が確定している必要があるのだ。 Janusコンポネントに対して、常に入力と出力の区別を要求するのは、このよ うな理由による。

「入力と出力を区別する」など、いくつかのお約束/お作法を守ってもらえ ば、後は計算機構(カルキュレーション・マシナリー)が動作する。実は、こ の計算機構が完全には定式化されてないし、その計算がコンピュータでエフェ クティブにできるかどうかも分からない。だが、部分的で不完全な計算機構で さえ、けっこう役に立つと僕は信じている。