2010/04/06

defmacro: LOL nif

LET OVER LAMBDA Edition 1.0
マクロを使えば、他の言語では全く不可能なことが可能になる。 --Doug Hoyte
define-syntaxの書き方や仕組みも良くわかっていないのですが、取り合えずトライ。
;; nif
(define-macro (nif expr pos zero neg)
(let ((g (gensym)))
`(let ((,g ,expr))
(cond ((positive? ,g) ,pos)
((zero? , g) ,zero)
(else ,neg)))))
(nif -1 1 0 -1)
; -> -1
(nif 1 1 0 -1)
; -> 1
(nif 0 1 0 -1)
; -> 0
(define-syntax nif
(syntax-rules ()
((_ expr pos zero neg)
(cond ((positive? expr) pos)
((zero? expr) zero)
(else neg)))))
(nif 1 1 0 -1)
; -> 1
(nif (let ()
(print 'hoge)
1) 1 0 -1)
;; hoge
;; 1
view raw nif.scm hosted with ❤ by GitHub

define-syntaxの方はexprに副作用があっても1回しか評価されてない、ということで良いのかな。あれ、「,g」を「, g」と書いてるがそれは良いのか?

追記

展開してみれば良いのか。
(macroexpand '(nif (let ()
(print 'hoge)
1) 1 0 -1))
(#<identifier user#cond>
((#<identifier user#positive?> #0=(let () (print 'hoge) 1)) 1)
((#<identifier user#zero?> #0#) 0)
(#<identifier user#else> -1))
view raw test.scm hosted with ❤ by GitHub


プログラミングGaucheLET OVER LAMBDA Edition 1.0

0 件のコメント:

コメントを投稿