Lisp本積読解消: Object-Oriented Common Lisp 11 Macros — #:g1

Posted 2017-02-25 20:18:30 GMT

今回は、Object-Oriented Common Lispのマクロの章を読む。
著者のStephen Slade氏はTの開発者として知られていて、Tについての著作もある。

各章の冒頭は古典からの引用で飾られていて随分知的な雰囲気がある。また語彙が豊富なので英語が苦手な自分のような人間には単語を辞書で確認しつつ読み進めるのが面倒臭い。

まず、Lispでは構文を拡張できることが説明され、repeatという繰り返し構文を作りながら解説が進む。

バッククォートの説明では、defmacroとの組み合わせの他にdeftypeにも言及されていて、これは少し珍しいと思った。

ちなみに、本書でも、Common Lisp Programming for Artificial Intelligenceのバッククォートの説明の箇所が引用されていた。

本書のマクロ作成解説で特徴的なのは、gensymを使わない所。
他の書籍では変数の捕捉問題には大抵gensymを使った対処方法が説明されているが、本書では、変数のスコープを別々にすることで対処する方法のみを説明する。具体的には、repeatのようなものは、

(defmacro repeat (n result &body body)
  `(flet ((body () ,@body)
          (result () ,result))
     (let ((n ,n))
       (do ((count n (1- count)))
           ((<= count 0) (result))
         (body)))))

(repeat 3 nil (print 'a)) ⊳ a ⊳ a ⊳ a → nil

のように本体や結果節を繰り返し構文の変数スコープの外に置くことで捕捉を防ぐ。

ただ上記のようにfletを使った場合、関数名のブロックが作られるため、

(repeat 3 nil 
  (progn (return-from body) (print 'a)))
→ nil

としてしまうと、ブロック名を捕捉できてしまうので、無名関数を使うなり関数名をgensymで生成するなりする必要があるだろう。
なお、本書では上記のような変数以外での捕捉問題の解説はない。

また、局所関数に展開する方法の他に、下請け用関数を定義するバージョンもあり(練習問題の解答で詳細が解説される)

Common Lisp Programming for Artificial Intelligenceでも紹介されていた方法だが、一歩進めた感がある。

次に、関数とマクロの比較、分配束縛、リーダーマクロと解説が進む。
リーダーマクロについては結構詳細な解説がある。

最後に進んだ話題として、リードテーブルの文字ケースの扱い、define-modify-macro、ディスパッチマクロ文字、*macroexpand-hook*について解説がある。

面白いのが、*macroexpand-hook*の解説で、traceのマクロ版を作成しつつ解説が進むが、何故かとてもボリュームがある(8頁も)。
コードが多いとはいえ、*macroexpand-hook*についてここまで詳しい本は他にないのではないだろうか。

練習問題も充実しているが、設問の意図がはっきりしないものが多く、またあまりマクロに関係無い問題もあり飛したくなる。

解答が巻末に付いているので、意味が分からない場合は、解答を見て意図を把握してから問題に取り組むと良いかなと思った。

気になった所

1997年出版であるので、ANS沿って説明かと思いきや、どうもCLtL2相当の説明らしくspecial-form-p等が普通に出てくる。

リードテーブルの扱いというのは、(copy-readtable rt nil)すれば良いのに、無駄なユーティリティを作成しているように見える点。

処理系依存コードについては、Allegro CLに依存しているらしいが、著者はどの辺りが処理系依存かはあまり把握していなさそう。

命名規約に沿わないというのは、スペシャル変数には、*earmuff*を付けるのが規格が採用しているマナー(というか謎のバグ防止)であるのに付けない所。

結び

マクロの章しか読んではいないが、どうも本書は脱線が多いのではないだろうか。
ディスパッチマクロのディスパッチという概念を解説するのに紙テープ時代の話を引用したりとか……。


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus