#で、free-identifier=?で比べればマクロに渡された:mixinsがグローバルなやつか再束縛されたやつかはわかるんだけど、たとえば:
#(define key :mixins)
(.... key arg)
#みたいにキーワード自体が隠されてる場合はマクロと手続き呼び出しで挙動が変わる。これをどう許容するかですね。
#これはsrfiのキーワードの議論でも大きな争点になったんだよな… キーワードをsyntacticに解釈する、つまり呼び出し側に常に明示的にキーワードが現れてなければならないとするなら、マクロと手続きで挙動を合わせることが可能なんだけど、その場合例えばキーワード引数の並びをリストにしといてapplyで渡す、ということができなくなる。
#Kawaはキーワード引数をsyntacticに解釈してて、うまい最適化もやってるんだけど、「キーワード引数を含む引数リストをapply経由で渡す」ということができない (特殊なapplyが必要)。自分はそれはSchemeの前提を崩すから嫌なんだけども。
#前提: (f a b c d)と呼び出せるなら、(let ((args (list a b c d))) (apply f args))とも呼び出せる
#うーん、なるほど。キーワードとはそもそもなんなのかとか、キーワードに対するリネームはどういう意味を持つのかとかを考えずに行き当たりばったりで修正すると、一貫性のない挙動に陥りかねない…という気持ちになってきました。それで暫定的な修正なんですね。
#キーワード自体が隠されている場合は、マクロというのはフォームを受け取るのであって変数を解決したりは普通しないので、そこの挙動が変わるのは自然な気がします。
#キーワード引数をsyntacticなものに、というのはよく考えます。自作言語作るなら熱心に検討したいですね。しかし、Schemeらしくないというのもわかります。
#import時のrenameでキーワードの束縛を付け替えた場合は、元の名前と同じキーワードと認識してほしいですよね?unwrapしてしまうと異なるものになってしまいますが、free-identifer=? で比較すればこれもいけるのでは…?(結局思い付きベースになってしまった)
#gosh> (use gauche.keyword :rename ((:name :namae)))
gosh> (define-syntax name? (er-macro-transformer (^ (f r id=?) (match f ((_ y) (id=? :name y))))))
#<undef>
gosh> (name? ':namae)
#f
#あれ、駄目なのか。
#gosh> (define-syntax syn-id=? (er-macro-transformer (^ (f r id=?) id=?)))
#<undef>
gosh> ((syn-id=?) ':name ':namae)
#t
#横着したら #t になったので騙されてしまった、それとも何か勘違いしている?
#あと最近のGaucheは free-identifier=? あるんですね。
#最初のやつはname?がマクロなので呼び出し側にクオートいらないです。 (name? :namae) => #t
#oops!
#でも単に (free-identifier=? ':name ':namae) だと #f になるんですよね
#free-identifier=?は識別子同士の比較です。識別子でないもの(シンボル)がきたら無条件で#fを返します。通常の手続きにクオートして渡しちゃうとlexicalな情報が剥ぎ取られるのでhygienicな比較はできません。
#上のsyn-id=?が動いてるのは、er-macro-transformerのid=?はその時点のlexical情報を知っていてそれをクローズしてるからです。なので生シンボルが渡ってくると、クローズしているlexical情報でもってrenameしてから比較するのでうまくいきます。
#free-identifier=? wo
#使いたいなら、er-macro-transformerの中でいったんrenameしてから渡す形になります
#なるほど、ありがとうございます。