2010/03/29

defmacro: fluid-let

マクロ
ほぼ写経ですが。
;; fluid-let macro
(define-macro (my-fluid-let xexe . body)
(let ((xx (map car xexe))
(ee (map cadr xexe))
(old-xx (map (lambda (ig)
(gensym)) xexe))
(result (gensym)))
`(let ,(map (lambda (old-x x)
`(,old-x ,x)) old-xx xx)
,@(map (lambda (x e)
`(set! ,x ,e)) xx ee)
(let ((,result (begin ,@body)))
,@(map (lambda (x old-x)
`(set! ,x ,old-x)) xx old-xx)
,result))))
(define x 100)
(define y 200)
(define (p)
(format #t "~a:~a\n" x y))
(p)
;; 100:200
;; #<undef>
(my-fluid-let ((x 10)
(y 20))
(p))
;; 10:20
;; #<undef>
(macroexpand '(my-fluid-let ((x 10)
(y 20))
(p)))
; -> (let ((#0=#:G70 x) (#1=#:G71 y)) (set! x 10) (set! y 20) (let ((#2=#:G72 (begin (p)))) (set! x #0#) (set! y #1#) #2#))
(display
(macroexpand '(my-fluid-let ((x 10)
(y 20))
(p))))
; -> (let ((G76 x) (G77 y)) (set! x 10) (set! y 20) (let ((G78 (begin (p)))) (set! x G76) (set! y G77) G78))#<undef>
;; (let ((G76 x)
;; (G77 y))
;; (set! x 10)
;; (set! y 20)
;; (let ((G78 (begin (p))))
;; (set! x G76)
;; (set! y G77)
;; G78))
view raw fluid-let.scm hosted with ❤ by GitHub

プログラミングGauche

0 件のコメント:

コメントを投稿