実践Common lispを読み始めた-第8章 マクロ:自分で定義しよう

自分でマクロを書いてみるところに入ってきた。

マクロを正確に理解する最大の障壁は、おそらくマクロがあまりにうまく言語に統合されてしまっていることにある。

はい、そうだと思います。マクロを使っていても言語を拡張しているという印象がまるでない。

マックはじめて物語り

ずいぶん出来すぎたはなしだなーと思ったら、作り話だった。

マクロ展開時 vs. 実行時

マクロを理解するためには、

  • マクロ展開時
  • 実行時

の2つを明確に区別すること。自分が読んだLisp本でこのことをきちんと説明しているのははじめて。インタプリタで動作しているときには境界がはっきりしないが、意識することにする。

マクロの定義

defmacroを使う。
マクロの作り方の手順としては、

  1. マクロ呼び出しのサンプルを書き、その展開形を書く。または展開形からマクロ呼び出しサンプルを書く。
  2. マクロの呼び出しのサンプルから1. で自分が書いた展開形を生成するコードを書く。(実際の引数を与えてmacroexpand-1関数を呼び出して表示されるマクロ展開結果が自分が展開したものと同じになればOK!)
  3. マクロによる抽象化に漏れがないことを確認する。気をつけないと行けない点は、マクロを評価するときの順序、部分フォームの評価される回数、展開形で使う変数はマクロ展開時にgensymを使って衝突しない変数名を作ること。

それ以外には

  • マクロの引数に固定個の要素を持った引数をセットさせることが決まっている場合、
(defmacro hoge (alist) ...)

とやらなくても

(defmacro hoge ((val1 val2)) ...)

と指定できる。

  • &restに似たもので&bodyというのがある。