eji
江尻です。
いろいろとGaucheにお世話になっています。 これからKahuaとかにも手を出していこうかなと思っています。
MLに出さないようなネタがあればこっちに
スペシャライザについて
最近,特定の文字列やシンボル,数値ごとにメソッドを定義できるたらいいなと思ってます。 あまり良い例だと思わないのですが(^^;
gosh> (define-method div (a (b := 0)) 'hoge) gosh> (define-method div (a b) (/ a b)) gosh> (div 4 0) hoge gosh> (div 4 2) 2 gosh> (define-method hoge ((num :>= 0)) 'positive) gosh> (define-method hoge ((num :< 0)) 'negative) gosh> (hoge 0) 'positive gosh> (hoge 3) 'positive gosh> (hoge -1) 'negative
適当に書いたので汚いパッチですが上記のように動くはずです。 パッチ
調べてみたらここで議論されてたっぽい。Shiroさんが考えているEQLスペシャライザ相当の機能ってどんな感じなんだろ? 早く使ってみたいな〜
Shiro(2006/04/03 11:35:36 PDT): なるほど、eql specializerみたいに等価性だけ でなくて、条件を指定できるようにするわけですね。 応用によってはおもしろいことが出来そうですが、コアに取り込むには難があります。
- 条件を満たすメソッドが複数あった場合にその順位を(method-more-specific?が) 決める決定的な方法がない。パッチでは比較で先に来た方が優先されるが、 どういう順序で呼ばれるかは自明でない。
- eji(2006/04/10 02:51:19 PDT): 反応が遅れてすみませんでした。この問題は述語に優先順位を与えて解決しようかと考えてました。例えば、"="の優先度を0、">="の優先度を1(数字の小さい方が優先度が高い)として以下のように動作させるつもりでした。優先度が同じものについては後から定義された順に呼び出すようにしたいと考えていました。
gosh> (define-method hoge ((a :<= 0)) 'negative) gosh> (define-method hoge ((a := 0)) 'zero) gosh> (define-method hoge ((a :>= 0)) 'positive) gosh> (hoge 0) 'zero
- method-more-specific? はメソッド呼び出しの度に複数回呼ばれるパスにある 処理なので、Scm_Applyを呼ぶのは重すぎる。
- eji(2006/04/10 02:51:19 PDT): Gaucheが用意している述語(eq?とかequal?)についてはScm_Applyを使わずに済ませることができそうなのですが、ユーザー定義の述語に関してはScm_Applyを使う以外に上手い方法が分かりませんでした。
私としては、「デフォルトにするには重いけれど、<generic>をサブクラスして こういう機能をつけ足すライブラリとしてならあっても良いかな」と思います。 そうするなら、specializers配列にclassしか入れられないって制限は取っておいた 方がいいかなあ。eql specializerはそのspecializer専用のクラスをon the fly で作成することを考えていたんですが、このパッチみたいにしてもいいかも。
- eji(2006/04/10 02:51:19 PDT): apply-genericでメソッドの適用をオブジェクトごとに変えられるようにするということでしょうか?