symbol-macrolet
symbol-macrolet の挙動をちゃんとわかってないことが判明したので sbcl で調べてみた。
operator は展開しない
(defun foo () 'DEFUN) => FOO (symbol-macrolet ((foo 'SYMBOL-MACRO)) (list foo (foo))) => (SYMBOL-MACRO DEFUN) (symbol-macrolet ((foo 'SYMBOL-MACRO)) (labels ((foo () 'LOCAL-FUNCTION)) (list foo (foo)))) => (SYMBOL-MACRO LOCAL-FUNCTION)
macro 展開で出現した symbol は展開する
(defmacro *foo () 'foo) => *FOO (macroexpand '(*foo)) => FOO (symbol-macrolet ((foo 'SYMBOL-MACRO)) (list foo (*foo))) => (SYMBOL-MACRO SYMBOL-MACRO)
shadowing された symbol は展開しない、マクロ展開で出現した symbol でも同様
(symbol-macrolet ((foo 'SM-FOO) (bar 'SM-BAR)) (let ((foo 'LEXICAL-VALUE)) (list foo (*foo) bar))) => (LEXICAL-VALUE SM-BAR LEXICAL-VALUE)
tag は展開されない
(let ((c 0)) (symbol-macrolet ((foo (print "hehehe"))) (tagbody foo (print (incf c)) (if (< c 3) (go foo) foo)))) 1 2 3 "hehehe" => NIL