関数とマクロでのクォートの扱いの違い
関数を生成するマクロ・その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 が記録されてしまったが、マクロだと期待通りの動作になった。マクロは式を返し、返された式が評価されて結果が出るが、関数はいきなり評価する。だから、できることとできないこと、長所短所をそれぞれ持つわけだが、今回の検証はその違いの一つと言っていいだろうと思う。