2010/06/29

syntax-rules: ext-let

CL とか Clojure の destructuring-bind があればそれで済みそうですが、Gauche にはどうやらなさげ?

syntax-rules だとこんな感じでしょうか。。
;; http://d.hatena.ne.jp/Shinnya/20100628/1277733558
(define-syntax ext-let
(syntax-rules ()
((_ (var ...)(val ...) body ...)
(let ((var val) ...)
body ...))))
(ext-let (a b)(1 2)
(print a)
(print b))
(ext-let (a b)()
(print a)
(print b))
(ext-let ()()
(print 'a))
(ext-let (a b)(1)
(print a)
(print b))
(ext-let (a b)(1 2 3)
(print a)
(print b))
(ext-let (a b c d e f g)
(1 2 3 4 5 6 7)
(print a b c d e f g))
view raw ext-let.scm hosted with ❤ by GitHub

これだと、(ext-let (a b)(1)(print a)) などでも動きます。(var ...) と (val ...) が同じ長さでない場合エラーにしたいって時はどうしたら良いのでしょうか。

追記

なんとなく希望に近い動きしてるように見えますが・・・。うーん・・・頭痛くなりますね。補助マクロとして切り出せば少しはマシに見えるのかもしれませんね。
(define-syntax ext-let
(syntax-rules ()
((_ "sub" ((var1 val1) ...)(var2 var3 ...)(val2 val3 ...) body ...)
(ext-let "sub" ((var1 val1) ... (var2 val2))(var3 ...)(val3 ...) body ...))
((_ "sub" ((var val) ...)()() body ...)
(let ((var val) ...)
body ...))
((_ ()() body ...)
(ext-let "sub" ()()() body ...))
((_ (var1 var2 ...)(val1 val2 ...) body ...)
(ext-let "sub" ((var1 val1))(var2 ...)(val2 ...) body ...))))
view raw ext-let2.scm hosted with ❤ by GitHub


追記2

こんな感じ?ヘルパー。
(define-syntax ext-let
(syntax-rules ()
((_ ()() body ...)
(ext-let-helper ()()() body ...))
((_ (var1 var2 ...)(val1 val2 ...) body ...)
(ext-let-helper ((var1 val1))(var2 ...)(val2 ...) body ...))))
(define-syntax ext-let-helper
(syntax-rules ()
((_ ((var1 val1) ...)(var2 var3 ...)(val2 val3 ...) body ...)
(ext-let-helper ((var2 val2)(var1 val1) ... )(var3 ...)(val3 ...) body ...))
((ext-let-helper ((var val) ...)()() body ...)
(let ((var val) ...)
body ...))))
view raw ext-let3.scm hosted with ❤ by GitHub


プログラミングGauche

0 件のコメント:

コメントを投稿