プログラミングGauche って、マクロの章すごく少ないですよね・・・。syntax-rules の練習問題というか例題というか、そういうのをたくさん見たい。ソース読め?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; update-if-true! | |
(define-syntax cond-set! | |
(syntax-rules () | |
((_ pred var init) | |
(if pred | |
(set! var init))) | |
((_ pred var1 init1 var2 init2 ...) | |
(if pred | |
(begin | |
(set! var1 init1) | |
(set! var2 init2) ...))))) | |
(define-syntax update-if-true! | |
(syntax-rules () | |
((_ (pred var)) | |
(let ((p pred)) | |
(cond-set! p var p))) | |
((_ (pred1 var1)(pred2 var2) ...) | |
(begin | |
(update-if-true! (pred1 var1)) | |
(update-if-true! (pred2 var2)) | |
...)))) | |
(define (test x y z) | |
(let ((x-is-big #f) | |
(y-is-zero #f) | |
(z-is-string #f)) | |
(update-if-true! | |
((> x 5) x-is-big) | |
((zero? y) y-is-zero) | |
((string? z) z-is-string)) | |
(values x-is-big y-is-zero z-is-string))) | |
追記
コメント欄より。cond-set!の2番目の節はおそらくやりたいことと違うのではないかと推察します。修正してみました。
init2だけが複数扱いになり、var2が繰り返されます。
(cond-set! a b c d e f g)
は
(if a (begin (set! b c) (set! d e) (set! d f) (set! d g)))
になります。(2番目以降、set!されてるのはすべてd)
cond-set!の2番目の節はおそらくやりたいことと違うのではないかと推察します。
返信削除init2だけが複数扱いになり、var2が繰り返されます。
(cond-set! a b c d e f g)
は
(if a (begin (set! b c) (set! d e) (set! d f) (set! d g)))
になります。(2番目以降、set!されてるのはすべてd)
マクロはちゃんと書こうとするとそれだけで大変になりそうだったので、『プログラミングGauche』では深入りを避けました。Schemeマクロのとってもディープな話はOleg Kiselyovさんのページ http://okmij.org/ftp/Scheme/macros.html をどうぞ。(注: 同ページにあるマクロはsyntax-rulesを限界まで酷使するんですが、Gaucheの実装は弱っちいので破綻します; 具体的にはマクロを定義するマクロでうまくいかないところが出ます)
試してみたところ、仰る通りの結果でした。修正してみます!
返信削除>マクロはちゃんと書こうとするとそれだけで大変になりそうだったので、『プログラミングGauche』では深入りを避けました。
そうだったんですか。確かにマクロまで詳細に書かれていたら、本の厚みがすごいことになりそうですね。。
Oleg Kiselyovさんって、The Reasoned SchemerとかSXMLの方ですよね?教えて頂いたページを読んでみます!ありがとうございます!