ふと LispUser.net のむかしの記事を見ていたところ、S式の限界と題して、 let と cond の記法拡張の話があった。端的に言うと、矢印が使えるようになるというもの。
で、最初に見たときは「あーまあそうだよね」という感じであり、まあサンプルとしては良いな、と思っていたわけだ。でまあそれだけだったんだけど、なんというか、わりと最近になってようやく自分でも define-syntax / syntax-rules で書くのに抵抗がなくなったというか、「こうすればできるじゃん」のイメージが掴めるようになったので、例題がてらにちょっとやってみた。
いい機会なので、 pyvnc2swf で撮影したムービーも公開します。というか、ムービー作成をちょっとやってみたかった、というのもある(笑)。
>
矢印let
>
矢印cond
裏をあかすと矢印letの方はやってみたらすぐ出来てしまい、それは撮影していませんでした。でもまあそれはそれとして、ということで lets を作ろうとしてから、ああ lets-sub にした方がいいね……とやっているのは、当初の行動を最初はちょっとトレースするためにわざとしたこと。でもそれ以外は素であり、脇に正解があるのを見ながらとか、そういうことはしていません。矢印 cond にいたってはぶっつけ本番であり、おかげさまで途中にどう考えてもしょーもないミスがあるのにオレがなかなか気付かないという、本物のハッカーな人にとってはある意味ハラハラドキドキの作品に仕上がってしまいました。ま、興味がありましたらどうぞということで。
さて、なんとなくやってみたのですが、このように並べると Common Lisp の伝統的なマクロと Scheme の健全なマクロでは、同じことをするのにどのように書くか、という違いがわかりやすくなる……のかもしれませんね。伝統的なマクロというのは、まさに Lisp の構文木を S 式として受け取り、 S 式を返す関数を書いてやるようなものなわけです。したがって、ふつうのリスト操作関数やシンボル系の関数を駆使して、ふつうの Lisp のプログラムのように書く。ところが健全なマクロではそういうことは実はできないために、いわばパターンマッチを繰り返して木の構造を少しずつ変化させていくという書き方をする。今回のような、任意長のボディを少しずつ見ながらその結果を溜めていくなケースでは、下請けのマクロを定義してやって、少しずつ変換させながら溜めていくというアプローチを取るのが一般的なようです(わたしは cut の定義をみてこれを学んだ、と思う)。まあ、できることはいっしょ(らしい)のだけれどやりかたは少し違いますね、という感じで、比べるのも申し訳ない気がするけれど Common Lisp の書き方と比べてもらえると幸い。ただまあ、「マクロも通常のプログラムもまったく同じように書ける」という Common Lisp と比べて、なんだかわけのわからない Scheme のマクロの書き方ってどうなの?という話はありますが。パターンマッチはオレには自然なので、これはこれでいいといえばいいんですが(とはいえ … のマジックっぷりには頭が下がる。超メンドくさそう)。
卒業に伴い、ヒビルテのURIを http://www.tom.sfc.keio.ac.jp/~sakai/d/ に変更しましたので、対応をよろしくお願いします。