マクロを書くのにもSeriesを使う — #:g1

Posted 2010-10-30 17:18:00 GMT

マクロを書くのにSeriesを使うというのは、なんとなく抵抗があるので、まずはこういうところから馴れて行くことにしました。
ごちゃごちゃしているので有名なONCE-ONLYで実験。

(import 'fare-utils:WITH-GENSYMS)

(defmacro once-only ((&rest vars) &body body) (multiple-value-bind (renames temps) (map-fn '(values symbol symbol) (lambda (var name) (values `(,name ,var) ``(,,var ,,name))) (scan vars) (map-fn 'symbol #'gensym)) `(let ,(collect renames) (with-gensyms ,vars `(let (,,@(collect temps)) ,,@body)))))

;; seriesのリーダーマクロを使った場合
(defmacro once-only ((&rest vars) &body body)
  (multiple-value-bind (renames temps)
                       (#2M(lambda (var name) 
                             (values `(,name ,var)
                                     ``(,,var ,,name)))
                           (scan vars)
                           (#Mgensym))
    `(let ,(collect renames)
       (with-gensyms ,vars
         `(let (,,@(collect temps))
            ,,@body)))))
;; 定義
(defmacro square (x)
  (once-only (x)
    `(* ,x ,x)))

;; 動作 (square (incf x))

;; マクロ展開 (LET ((#:G1239221 (INCF X))) (* #:G1239221 #:G1239221))

意外にもONCE-ONLYはすっきり書けました。試してみるもんです。

comments powered by Disqus