#関数に対してhashを定義するにはどうすれば適切なのでしょう? eq?で比較できるということはhashも定義できるのではないかと思うのですけれど。
#関数の等価性については色々議論がありますが、eq?によるポインタ比較以外で意味のある比較はできないと思います (任意の二つの関数のふるまいが同じかどうかを調べるのは停止性問題と等価で不可能だったんじゃないかな)。eq?に対応するハッシュ値なら今でもeq-hashで計算できます。具体的に何がしたいですか?
#aというデータにたいして、fnという関数をペアにします。 aとfnをペアにしてある処理をするのですが、その結果をキャッシュしたいわけです。
#; type --> node のテーブル
(define *info-node-names-jp*
(alist->hash-table
`((function ,*info-node-name-function-jp* ,gauche-menu-key-converter)
(variable ,*info-node-name-variable-jp* ,gauche-menu-key-converter)
(class ,*info-node-name-class-jp* ,gauche-menu-key-converter)
(module ,*info-node-name-module-jp* ,gauche-menu-key-converter) ) ) )
(define *info-node-names-en*
(alist->hash-table
`((function ,*info-node-name-function-en* ,gauche-menu-key-converter)
(variable ,*info-node-name-variable-en* ,gauche-menu-key-converter)
(class ,*info-node-name-class-en* ,gauche-menu-key-converter)
(module ,*info-node-name-module-en* ,gauche-menu-key-converter) ) ) )
#たとえば、functionで引っ張ってきた node-nameとconverterをキーにしたhashは定義できるのであろうかと。
#うまく表現できていない気がします・・・・(汗
#;索引ノードを取得する
; info node-name ---> <info-index-node> or #f
(define-method get-index-node ((info <info-file>) (node-name <string> ) key-converter)
(and-let* [[node (~ info node-name)]]
(make <info-index-node> node key-converter ) ) )
#このget-index-nodeをメモ化したいわけなんです。
#あとで、いまの段階のコードをwilikiに上げます。(「Gauche:マニュアルにアクセス」)
#どうしてもhash使いたいならconverterの部分を無視したハッシュ値を返すとか、あるいはeq-hashの値を使うとかですね。ハッシュ値の要件は「aとbが等価ならば(hash a)と(hash b)は等しい」ってだけで、例えば「常に1を返す関数」であっても間違いではないです (性能的には最悪のハッシュ関数ですが)。今回の場合、node-nameが同じでconverterだけ違う引数の組み合わせが100万個あるとかそういうわけじゃないので、converter部分は無視したって大したこと無いんじゃないかと。
#なるほど。そういうふうに考えればいいわけですね。ありがとうございます。
#(無視というのはhash値の計算に使わないというだけで、等価性の判定には使います。)
#get-index-nodeのその例なら、get-index-node自体をメモ化するより<info-index-node>をinstance poolにする (gauche.mop.instance-pool) 方がわかりやすいかなと思います。
#ありがとうございます。こういう便利なものがあったのですね!