Gauche:組み込みオブジェクトのカスタマイズ

Gauche:組み込みオブジェクトのカスタマイズ

Q. なぜ組み込みオブジェクトの継承は許されていないのか

hisashim (2009/07/04 Shibuya.lisp TT#3懇親会にて) stringを継承しようとしたら、

gosh> (define-class <my-string> (<string>) ())
*** ERROR: class '<my-string>' attempted to inherit from a builtin class #<class <string>>; you cannot subclass a builtin class.

とオブジェクトシステムに怒られました。

Shiro 継承を許した場合、例えばあるオブジェクトobjがstringであることを確認 するために、objのクラスの継承チェインを最悪で全部たどる必要があります。 (objがstringであれば最初のチェックで一致しますし、stringのdirect subclass でも一回チェインをたどれば一致するのでまあ問題無いんですが、「外れ」だった場合の コストがかなり大きくなります)。

ただ、これはあくまで継承を使う話であって、目的がプロパティをつけたいという 話であれば継承なしに直接個々のインスタンスにそういう機能をつければいけると 思います。

immutable objectのプロパティをどう考えるべきか (immutableなんだから プロパティも変更不可にすべきか) という別の話は出てくるのですが。 (immutable objectはその性質を利用して、裏で最適化のためにコピーされたり 共有されたりするかもしれず、そうなるとプロパティが変更可能だとややこしいことに なります。)

hisashim 非標準のオブジェクトの取り扱いがコスト高になるのは理解できるの で、もし可能なら、承知のうえでやりたい人には道が残されているといいなあ と思います。 クラス継承かどうかにこだわりはなく、出来合いのものを少しカスタマイズし て楽に目的を達成したいだけなので。

(文字列の場合は、たしかにimmutableであることのメリットのほうが大きそ うなので、状態を持たせたいなら、文字列をメンバに持つオブジェクトを定義 して使うのが筋なのでしょうね。文字列ではないものに文字列操作用の各種メ ソッドをうまく定義するのはややこしそうですが、無理ではなさそう。)

Shiro 継承を許すと、標準のオブジェクトの処理が全部コスト高になっちゃう、ということです。 (「文字列かどうか」みたいなチェックはCレベルのマクロでも多用されてるんで、 再コンパイルしないと継承許可/不許可バージョンが切り替えられません) 同様に、string-* 系の組み込み関数の振る舞いをいじれるようにするのは やっぱり標準動作の性能に大きな影響を与えます。

プロパティによるカスタマイズはありだと思います。もっとも、オブジェクトに プロパティをつけたいなら(効率を考えなければ)今でもweak-hash-tableを 使えば可能…と書きかけて確かめたらSchemeレベルでweak-hash-tableの APIを公開してませんでしたね。 eq-hashとweak-vectorを使って自前でweak hash tableを実装すれば 今の段階でもユーザレベルで任意のオブジェクトにプロパティをつけることは 可能ではあります。でも面倒くさすぎるなあ。

効率が悪くていいなら文字列をメンバに持つクラスにsequenceプロトコルを 実装して、全部generic functionで扱っちゃうって手はあります。 あーでも組み込みのstring-*を使ってる手続きに自前オブジェクトを渡したい ってことはあるのか。

これ以上は具体的なケースを見ないとわからないですね。

More ...