言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

オープンクラスとはダイナミックスコープだという話。

http://blog.livedoor.jp/dankogai/archives/51507869.html を読んで、これは書かなきゃ!と思ったので、まだ考え途中だけどメモします。私のネームスペース理論で言うと、オープンクラスとはダイナミックスコープなのです。

まずオープンクラスとは何かざっと復習。Java 等の静的なオブジェクト指向言語では、クラスを定義する時に全部のメソッドを書く必要があるけど、SmalltalkRuby のクラスでは、あとからメソッドを追加したり書き換える事が出来ます。こういうのをオープンクラスと言います。オープンクラスの凄い所は、メソッドを変更する前にもともとあったプログラムの振る舞いまで変わってしまうと言う事です!これは柔軟であると同時に大変危険な諸刃の剣です。

次にダイナミックスコープとは何かをざっと復習。変数が使われている場所ではなく、処理の流れを元に変数の意味が決まるやつをダイナミックスコープと言います。Emacs LispPerl など、古い言語で使われています。サブルーチンに入る時に古い変数を保存し、出る時に戻すという簡単な処理で実現出来るのでインタプリタに向いています。最近の言語のように変数が書いてある場所だけでスコープが決まるやつはレキシカルスコープと言います。

さて、ここで面白いのは、オブジェクト指向言語で使われるオブジェクト (データ構造 + 処理) とクロージャ (関数 + 関数に閉じ込められた変数) は同じ物だという考え方がある事です。実際に Smalltalk-71 のオブジェクトはアクティベーションレコード(関数実行中のメモリ構造)を永続化する事をヒントに作られました。つまり、クロージャとオブジェクトは見かけが違うだけで同じものなのです。

しかし、もっと細かい所を観察すると、色々面白い事が分かってきます。もしもクロージャの中で参照される変数がレキシカルスコープだったら、外から意味を変更する事が出来ないので、クローズクラスと同じ事になります。しかし、もしもダイナミックスコープで、呼ばれる場所によって意味が変わったら?(普通こういうのはクロージャと言わないけど。。。)なんと、オープンクラスと同じ事がクロージャでも実現出来てしまいます!

なんでこういう瑣末な事にこだわるかと言うと、美しいデザインというのは、「なんとなく便利だから」とかじゃなくて、ちゃんと理由があるはずだ!と思ってるからです。

さて、実際のコードサンプルで見てみましょう。と書いた所でコードサンプルを Perl で書くか Common Lisp で書くか迷い中。つづく。。。

(注意: 考えながら書いてるのででたらめの可能性があります。考え始めたきっかけは、アクティベーションレコードが Javascript のプロトタイプチェーンで出来ていたらというアイデアです。まとまるまでしばらくお待ちください。というか本当に間違っているので信用しないで下さい。)