2012年4月28日土曜日

Scheme第8歩


マクロの話その2。
マクロはそのプロシージャの実行結果で置換されるのだが、実行結果が所望のS式になるようにあちこちquoteして周るのは、なかなか面倒かつややこしい。それを多少は改善してくれるのがquasiquote。

quasiquoteは、ほとんど全部quoteしたいのだけれど、部分的にquoteしたくない要素もあるリストを構築するとき、便利なもの。quasiquoteの中で例外的にquoteしたくない部分をunquoteする。リストの展開まで行うunquote-splicingも使える。

手っ取り早く使用例。第2引数のリストの合計に第1匹数を掛けるマクロを、まずはquasiquoteを使わずに定義してみる。
(define-macro
  gained-sum
  (lambda (a xs) (list '* a (apply list '+ xs)))
)
このマクロを
(gained-sum 10 (1 2 3 4 5))
のように使用すると、
(* 10 (+ 1 2 3 4 5))
と展開されるのだが、まあ、はっきり言ってマクロ定義は分かりにくい。そこでquasiquoteを使うと、
(define-macro
  gained-sum-qq
  (lambda (a xs) `(* ,a (+ ,@xs)))
)
マクロ定義が、マクロ展開結果にだいぶ近付いて見える。
ちなみに`xは(quasiquote x)、,xは(unquote x)、,@xは(unquote-splicing x)の略記法。専ら略記法しか使わなさそうだが。

マクロ内で使用するローカル変数の話は、次回に持ち越し。

0 件のコメント:

コメントを投稿