Ungar と Smith の “Self: The power of simplicity” を読んでいて、彼らが Self のメソッドの引数と局所変数を Self オブジェクトのスロットにしたがっていた理由が腑に落ちなかった。極端な純粋主義かもしれないし、オタク的な趣味なのかもしれないと思っていました。今日、ぼんやりとその意義が見えたような気がするので、記事を書く気になりました。
今日、JavaScript で Singleton パターンでプログラムを書いていて、JavaScript の動的な機能を用いて、
make_singletons(“a”, “b”, “c”);
と書くだけで、
a = new_singleton(“a”);
b = new_singleton(“b”);
c = new_singleton(“c”);
と同等のことをしたいと思ったのですが eval を使わない限り無理なことにきづきました。あたりまえのことかもしれないけれども、JavaScript の動的な性質は JavaScript オブジェクトのスロットに対する自己反映的な操作が許されていることに依拠するのですが、上でやろうとしていたのは a, b, c という変数を追加する操作だから基本的には無理ということです。
でも、もしかしたら Self だったら、こういうこともできてしまうのではないでしょうか。今、前述の論文を読み返してみたら、メソッドの引数も局所変数もそれぞれオブジェクトのスロットとして領域が割り当てられているようです。それぞれのオブジェクトに “a”, “b”, “c” という名前のスロットを割り当てれば変数としてアクセスできるようになりそうです。
というか、Self には変数という概念が希薄ですべてがスロットアクセスということになっているのだから、実は同等のことは JavaScript でやろうと思えばできるけれど、それは不自然なやり方になるというのが正しいのかな。((Self の論文ばかり読んだあとで JavaScript のプログラムを書いていて、関数やそのプロトタイプにスロットを追加してもそれが変数として参照できないことに悩んだりしたりしました。))
逆に言うと、Self の言語設計の狙いとしては、従来の言語のメソッド、フィールド、変数などをすべてスロットで置き換え、それに対しての実行時のアクセスを許すことで、高いレベルの自己反映機能を提供することがあったのかもしれません。
なるほど。ただ、自然/不自然を言うならJavaScriptであっても環境をreifyしさえすれば同等の自己反映機能が自然な形で得られるのではないか、という気もします。
JavaScriptでは引数はargumentsオブジェクトで触れるんですよね。ちょっと中途半端な感じはしますね。
もうひとつの方法として var 文のないサブセットに制約してプログラムを作ればできるかもしれませんね。
arguments は Lisp の &rest のようなものだと見做せませんか?