define-syntax ためしてみる。

しばらく前からちょくちょく SICP 眺めてる。読み始めた頃からけっこう Scheme に興味あるんだけど、あいつは言語としては Scheme 使ってるけど、Scheme の本じゃない。そんなことに気がつくのに結構な時間がかかりました。

というわけで、SICP 読み進めても一向に出てこない define-syntax で switch 文を定義してみます。別に switch 文が欲しいわけじゃないけど。たぶん cond で済みますよね。

(define-syntax switch (syntax-rules ()                          
 ((switch test ((v1 e1))) (if (equal? test v1) e1 #f))                
 ((switch test ((v1 e1) (v2 e2) ...)) (if (equal? test v1) e1 (switch test ((v2 e2) ...))))))
;#<undef>
(switch 'hoge (('piyo 'kuma) ('hoge 32)))                            
;32

うんちゃんと返ってるように見えますね。でも、この定義だと (switch 'hoge (('piyo 'kuma) ('hoge (write 'piyo) (newline)))) とかできない。いちいち begin とかめんどい。ので、

(define-syntax switch (syntax-rules ()                                
 ((switch test ((v1 e1 ...))) (if (equal? test v1) (begin e1 ...) #f))
 ((switch test ((v1 e1 ...) (v2 e2 ...) ...))                          
  (if (equal? test v1) (begin e1 ...) (switch test ((v2 e2 ...) ...))))))
;#<undef>

(switch 'hoge (('piyo 'kuma) ('hoge (write 'piyo) (newline))))    
piyo
;#<undef>

できた。あんまし調べずに書いたんですけど、syntax-rules さんの読解力には驚きました。

test