kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

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でかこんでやります