mokeheheのScheme日記

ツッコミ、添削大歓迎です。いろいろ教えてください。

2008-01-03

[] Practical Common Lisp第7章 マクロ

わずか7章でもうマクロキター

  • 条件式やガベージコレクションなど、Lispをオリジナルにする多くのアイディアが他の言語に影響を与えた一方、引き続き Common Lisp を特別なものにしている特徴は、マクロのしくみだ。
  • しかし、違う意味のマクロが広まってるおかげで、Common Lispマクロがいかにすばらしい特徴かを説明するのに苦労する
  • プログラミング言語を、言語コア+標準ライブラリと定義すると、理解しやすく実装しやすくなる
    • しかし、本当の利点は表現力にある
    • 言語をライブラリだけと考えれば、その言語は簡単に拡張できるでしょ?
  • マクロを使えば、新たな文法を作ることができる
when と unless
  • if の then, else には式をひとつしか与えられないので、それ以上の式を与えたい場合 progn を使う必要がある
    • if と progn を一緒にやってくれるのが欲しい
    • それ when でできるよ
(defmacro mywhen (condition &rest body)
  `(if ,condition (progn ,@body))) 
  • 取るに足らないマクロの例だけど、利点はでかい
cond
  • if ... else が複数つながると、インデントも深くなるし醜い
  • cond でスッキリ
and, or, not
  • and は偽が現れた時点で、orなら真が現れた時点で、残りの評価を打ち切る、のでマクロで定義される
ループ
  • Lispの25の特殊オペレータは直接ループ構造をサポートしてはいない、マクロが構築している
  • do: 汎用
    • dolist, dotimes: リスト、回数ループに特化したもの
  • loop: ミニ言語ぽい、Lispらしからぬ、英文ぽいループ用マクロ
    • 賛否両論
dolist と dotimes
do
(do (variable-definition*)
    (end-test-form result-form*)
  statement*) 
  • do を使ってフィボナッチ数の計算
オールマイティなloop
(loop
  body-form*)  
  • 複雑な使い方:
    • (loop for i from 1 to 10 collecting i) ==> (1 2 3 4 5 6 7 8 9 10)
    • (loop for x from 1 to 10 summing (expt x 2)) ==> 385
    • (loop for x across "the quick brown fox jumps over the lazy dog" counting (find x "aeiou")) ==> 11
  • (loop for i below 10 and a = 0 then b and b = 1 then (+ b a) finally (return a))
  • 22章で詳しく説明
  • loopはwhenやifよりちょっと複雑なだけで同じマクロだから、もしloopが標準ライブラリになかったとしても自分で実装できるよ
"Practical Common Lisp"を読んでる方:
トラックバック - http://sicp.g.hatena.ne.jp/mokehehe/20080103