letのマクロ
letのマクロがどう展開されるか実験する。
本節では、導出式型をプリミティブ式型(リテラル、変数、手続き呼び出し、lambda、if、set!)に置き換えるマクロ定義を示す。
http://www.swiss.ai.mit.edu/~jaffer/r5rsj_9.html#SEC81
Gaucheのletは組み込みのSpecial Formでマクロではないので、R5RSの定義で上書きする。
(define-syntax let (syntax-rules () ((let ((name val) ...) body1 body2 ...) ((lambda (name ...) body1 body2 ...) val ...)) ((let tag ((name val) ...) body1 body2 ...) ((letrec ((tag (lambda (name ...) body1 body2 ...))) tag) val ...))))
上記の定義をしてから、まずは普通に展開
gosh> (macroexpand '(let ((x 1) (y 2)) (+ x y))) ((#<identifier user#lambda> (x y) (+ x y)) 1 2) gosh> (macroexpand '(let name ((x 1) (y 2)) (+ x y))) ((#<identifier user#letrec> ((name (#<identifier user#lambda> (x y) (+ x y)))) name) 1 2)
#
(define (map* f l) (map (lambda (x) (if (pair? x) (map* f x) (f x))) l)) (define (if-id x) (if (identifier? x) (identifier->symbol x) x))
これを使ってもう一度やってみる。
gosh> (map* if-id (macroexpand '(let ((x 1) (y 2)) (+ x y)))) ((lambda (x y) (+ x y)) 1 2) gosh> (map* if-id (macroexpand '(let name ((x 1) (y 2)) (+ x y)))) ((letrec ((name (lambda (x y) (+ x y)))) name) 1 2)