RacketのMacroを調べてみる (4)
なんと下書きだけしてアップしてなかった分が!
----
再掲
> (define-syntax (our-if-v2 stx)
(define xs (syntax->list stx))
(datum->syntax stx `(cond [,(cadr xs) ,(caddr xs)]
[else ,(cadddr xs)])))
めでたい?
dの数とか数えたくないですね?
パターンマッチが使えます
同じ内容をパターンマッチで書くとこうなります
> (require (for-syntax racket/match))
> (define-syntax (our-if-using-match stx)
(match (syntax->list stx)
[(list name condition true-expr false-expr)
(datum->syntax stx `(cond [,condition ,true-expr]
[else ,false-expr]))]))
これでdを数えなくて済みます
こうでないと
matchはいろいろ書けるみたいなんですが実はまだよく知りません
(require (for-syntax racket/match)) というのはmatchを使うために必要なおまじない
もう少し詳しく言うと、Racketのソースが実行されるタイミングには2種類あります
compile timeとrun time、またはsyntax phaseとruntime phaseとも言います
普通にプログラムが実行中なのがrun timeで、
ソースをコンパイルしてるときがcompile time
マクロ、というかsyntax transformerはcompile timeに実行されます
で、compile time中に使えるライブラリは、run time中に使えるライブラリより
絞ってあります
matchは絞られてしまってるので、requireで使うよと言ってるわけです
for-syntaxっていうのはcompile time中に使うよ、という意味です
compile-time中に使いたい関数を自分で定義する場合は
defineの代わりにdefine-for-syntaxを使うか、
あるいはdefineをbegin-for-syntaxでかこんでやります