Memoize

BasicWerk   EC Support   Technique   Facebook  

20140816010508_Common_lisp_macro_backquote

Common_lisp_macro_backquote

 

 

`(backquote) されたリストの中で , でエスケープされた S 式は展開される。

 
* `(there is a list ,(mapcar (lambda (x) (format nil "item_~A" x)) '("A" "B" "C")))
 
(THERE IS A LIST ("item_A" "item_B" "item_C"))
 
;; ,@ とするとリストの要素が取り出されてそこに置かれる
* `(there are items ,@(mapcar (lambda (x) (format nil "item_~A" x)) '("A" "B" "C")))
 
(THERE ARE ITEMS "item_A" "item_B" "item_C")
 

 

mapcar のように何か処理をしてリストを返す高階関数を使うと次のようなことが macro の中で出来る。

 
;; 引数のシンボルにそれぞれシンボルの名前(文字列)を束縛する
(defmacro self-binds (syms &body body) 
 `(let ,(mapcar (lambda (s) (list s (symbol-name s))) syms) 
     ,@body))
 
* (self-binds (a b c) (format t "~S ~S ~S~%" a b c))
"A" "B" "C"
NIL
 

 

let 式は (let ((sym val) ...) ...) の形をとるから、mapcar はリストのリストを返している点に注目。

macroexpand-1 してみよう。

 
* (macroexpand-1 '(self-binds (a b c) (format t "~S ~S ~S~%" a b c)))
 
(LET ((A "A") (B "B") (C "C"))
   (FORMAT T "~S ~S ~S~%" A B C))
T
 

 


© Shin Nakamura/BasicWerk 2014