Shammer's Philosophy

My private adversaria

関数を生成するマクロ・その2

とあるパッケージの中で、とある関数を宣言してから、それを外部で使用させるためにエクスポートする、という処理を行う必要があるが(まあ、エクスポートしなくても unintern されていなければ::でアクセスできるのだが)、これをやるのが結構めんどくさいし、ソースコードも雑になる。しかも、アクセッサについてはほぼ外部に公開する必要がある。というわけで、この処理のコードもマクロに含めてしまおう、となった。関数を生成するマクロ・その1 - Shammerismで書いたコードに export の処理を追加。

? (defmacro generate-semaphore-accessor (name)
  `(let ((semaphore (make-semaphore)))
     (defun ,name ()
       semaphore) 
     (export ,name)))
GENERATE-SEMAPHORE-ACCESSOR
? (generate-semaphore-accessor get-my-semaphore)
;Compiler warnings :
;   In an anonymous lambda form at position 29: Undeclared free variable GET-MY-SEMAPHORE
> Error: Unbound variable: GET-MY-SEMAPHORE
> While executing: #<Anonymous Function #x302000F88DEF>, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.
1 > a

? (get-my-semaphore)
#<SEMAPHORE #x302000F87D9D>
? (defmacro generate-semaphore-accessor (name)
    `(let ((semaphore (make-semaphore)))
       (export ,name)
       (defun ,name () semaphore)))
GENERATE-SEMAPHORE-ACCESSOR
? (generate-semaphore-accessor get-test-01-semaphore)
;Compiler warnings :
;   In an anonymous lambda form at position 29: Undeclared free variable GET-TEST-01-SEMAPHORE
> Error: Unbound variable: GET-TEST-01-SEMAPHORE
> While executing: #<Anonymous Function #x302000FAE6FF>, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.
1 > q
? (export 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

? (defmacro export-1 (name)                   
    `(export ',name))
EXPORT-1
? (export-1 get-test-01-semaphore)
T
?

最初はエラーばかりだったけれども、export は引数をクォートしていないといけないのに対し、defun は真逆というのが原因のようだ。マクロをうまく機能させるには、',という形でシンボルを評価しなければならないこともあるようだ。うーむ。。。まだまだ覚えないといけないことはたくさんありそうだ。