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 |