#:g1: defmacro-enhanceの紹介

Posted 2014-01-18 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の19日目です。

defmacro-enhanceとはなにか

 defmacro-enhanceは、Alexander Popolitov氏作のLet Over Lambdaのdefmacro!の考えを拡張したdefmacro系のユーティリティです。

パッケージ情報

パッケージ名defmacro-enhance
Quicklisp
CLiKihttp://cliki.net/defmacro-enhance
Quickdocshttp://quickdocs.org/defmacro-enhance

インストール方法

(ql:quickload :defmacro-enhance)

試してみる

 どんな関数があるかは、Quickdocsで確認できます。

 基本的にLet Over Lambdaのdefmacro!を拡張したものなので、g!でのgensym指定や、o!での多重評価防止は同じです。

(defmacro-enhance:defmacro! foo (g!-a e!-b o!-c)
  `(list ',g!-a ',e!-b ',o!-c))

(foo a b 'c) ;=> (#:A3066 B #:O!-C3067)

(defmacro-enhance:defmacro! square (o!-x)
  `(* ,o!-x ,o!-x))

(square (incf x))

; ===> ; (LET ((#:O!-X3072 (INCF X))) ; (* #:O!-X3072 #:O!-X3072))

 拡張されているのは、e!というもので、展開先のパッケージの中にシンボルがinternされるというものです。

(defmacro-enhance:defmacro! aif (test then &optional else)
  `(let ((,e!-it ,test)) 
     (if ,e!-it
         ,then
         ,@(if else `(,else)))))

(let ((*package* (find-package :keyword))) (macroexpand '(cl-user::aif x it nil))) ;=> (LET () ; (LET ((:IT X)) ; (IF :IT ; IT))) ; T

 アナフォリックマクロでは、itやselfの所属するパッケージが問題になったりしますが、この問題を解決しようというものかなと思います。

まとめ

 今回は、defmacro-enhanceを紹介してみました。
e!は単にマクロ展開時にinternするだけのものですが、定義時に指定できるというのがなかなかのアイデアですね。

comments powered by Disqus