next up previous contents
Next: UNIX 関連 Up: 関数定義 Previous: ( defun vfname

( defmacro vmname gvars g 1 g 2 ... g n) SPECIAL

defmacro はマクロを定義する。全ての引数は評価されない。

defmacro で定義された関数では、その関数への全ての引数はリストとしてま とめられ、gvars に束縛される。例えば以下の定義を見てみよう。

(defmacro spread-value x
  (if (not (null (cdr x)))
     (cons 'let
            (cons (list (list 'spread-tmp-val (car x)))
                  (make-setq-form (cdr x)) ))) )

(defun make-setq-form (l)
  (if (null l) nil
    (cons (list 'setq (car l) 'spread-tmp-val) (make-setq-form (cdr l))) ))

マクロ関数 spread-value への引数はリストにまとめられ x に束縛される。 例えば、

(spread-value 5680 iroha canna)

と言う呼び出しの場合は (5680 iroha canna) が x に束縛される。

さて上記の定義で、make-setq-form は引数に与えられた物に対して spread-tmp-val を setq する式を作成する。

-> (make-setq-form '(a b))
((setq a spread-tmp-val) (setq b spread-tmp-val))

マクロ spread-value の本体は変数リストの各変数に対して x の car 部にあ る引数を let 式を組み合わせて代入する lisp 式を生成する。

例えば、x が (0 a b) であるならば、defmacro で与えた本体は以下の式を生 成する(ここでは見やすさのためプリティプリントしている)。

(let ((spread-tmp-val 0))
  (setq a spread-tmp-val)
  (setq b spread-tmp-val) )

マクロ式では、 defmacro で与えられた本体により得られる式をもう一度評価 する。上の例で spread-value を以下のように呼び出した場合、

-> (spread-value 5680 iroha canna)

は、あたかも、

-> (let ((spread-tmp-val 5680))
     (setq iroha spread-tmp-val)
     (setq canna spread-tmp-val) )

を実行したかのように評価が行われ、変数 iroha および canna には 5680 が 束縛される。

ここで、spread-value の第一引数だけは評価が行われ、その他の引数は全く 評価されないことに注意されたい。

このようにマクロはスペシャル型の関数のように、一部引数が評価されない関 数を作成するのに用いられる。

なお、Common Lisp などには defmacro を助ける記法としてバッククオート マクロ(lisp reader により処理されるマクロ記述)を用いることができるが、 canlisp ではバッククオートマクロはサポートしていない。



Riichiro Saito
1995年08月31日(木) 17時10分21秒 JST