Lisp本積読解消: Realm of Racket — ).3 Racket Is a Metaprogramming Language — #:g1

Posted 2017-03-03 20:27:07 GMT

今回は、Realm of Racketのマクロの箇所を読む。
Realm of RacketはLand of LispのRacket版のような感じで、Conrad Barski氏も著者の一人。
とはいえLand of Lisp程個性が強くないので物足りない人もいるかもしれない。

マクロの解説は、最後の章(Good-Bye)で

という風にメタプログラミング度を増して解説していくうちの3番目にあたる。

).3 Racket Is a Metaprogramming Language

Racketは他のLisp方言と比べても一番強力かつ表現力が高いという前置きがある。
とはいえ、この章ではそこまで詳しくは解説せず、言語の構文を拡張する方法として簡単なマクロを解説するのみ。
主にRacketで用いられるdefine-syntaxsyntax-rulesを合体したような、define-syntax-ruleを利用するが、それ程つっこんだ解説はしない。

(define-syntax-rule
  (my-and a b)
  (if a b #f))

衛生マクロなので変数捕捉等については特に気にする必要はないが、一応わざと大域変数とマクロ内で利用している変数の名前を衝突させてみたりしても上手く動きますねという解説がある。

次に、パタンマッチの書式の簡単な解説として、lambdaに展開されるletを作成しつつ説明する位で終了。

).4 Racket Is a Programming-Language Programming Language

マクロの応用として、DSLを作ってみせる内容だが、Racketのモジュールと#langの仕組みを使ってデバッグプリント付きの言語から、Racketに遅延評価を導入してみせたりする。

遅延評価の導入については、Racketで関数適用は、%#appを利用していて、これを差し換えることによって実現する。

この機構のお蔭でevalに手軽にフックを掛けるようなことができ、マクロともリーダーマクロとも違う第三の拡張方法という感じ。

ちなみに、evalにフックを掛ける機構は、Common Lisp系でも*evalhook**applyhook*というものが存在したが、インタプリタ動作とコンパイラ動作の整合性向上のためにANSI Common Lispでは廃止になっている。

結び

Racketが強力というのは良く耳にはするが、あまり触ったことはなかった。
メタプログラミングについては、確かにかなり洗練されていて強力そうだなと感じたので、もうちょっと遊んだりしてみたい。


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus