Shammer's Philosophy

My private adversaria

関数とマクロでのクォートの扱いの違い

関数を生成するマクロ・その2 - Shammerismで、export と defun ではクォートの期待値が異なることで問題が発生した。この問題を解決するため、エクスポートでもクォートなしで情報を渡すことができるようにしたい。とりあえず思いついたのが以下。

? (defun public-symbol (s)
(export (quote s)))
;Compiler warnings :
;   In PUBLIC-SYMBOL: Unused lexical variable S
PUBLIC-SYMBOL
? (public-symbol get-test-01-semaphore)
> Error: Unbound variable: GET-TEST-01-SEMAPHORE
> While executing: CCL::CHEAP-EVAL-IN-ENVIRONMENT, in process listener(1).
> Type :GO to continue, :POP to abort, :R for a list of available restarts.
> If continued: Retry getting the value of GET-TEST-01-SEMAPHORE.
> Type :? for other options.
1 > q
?

しかし、結果は上記の通り。関数内で引数を QUOTE してしまうと処理自体がおかしくなるようだ。'a は (QUOTE a) と同じだったと思ったが。いずれにせよ、関数でできないのでマクロを使用してやってみた。

? (defmacro public-symbol (s)
`(export ',s))
; Warning: The function PUBLIC-SYMBOL is being redefined as a macro.
; While executing: (SETF MACRO-FUNCTION), in process listener(1).
PUBLIC-SYMBOL
? (public-symbol get-test-01-semaphore)
T
?

同名の関数を定義した直後に同名のマクロを定義したから余計な Warning が記録されてしまったが、マクロだと期待通りの動作になった。マクロは式を返し、返された式が評価されて結果が出るが、関数はいきなり評価する。だから、できることとできないこと、長所短所をそれぞれ持つわけだが、今回の検証はその違いの一つと言っていいだろうと思う。