Shiro Kawai
shiro****@lava*****
2005年 4月 22日 (金) 11:54:55 JST
From: Makoto Satoh <makot****@yahoo*****> Subject: [Gauche-devel-jp] CommonLisp の defmacro の &body 相当について Date: Fri, 22 Apr 2005 11:26:21 +0900 (JST) > (defmacro with-image ((name width height &optional true-color) &body body) > (rebinding (width height true-color) > `(with-safe-alloc (,name > (create-image ,width ,height ,true-color) > (destroy-image ,name)) > , @ body))) > > この「&body body」の前に「&optional true-color」がありますが、Gaucheでは > そのままでは書けませんよね? CLのdefmacroは、パターンマッチによる束縛もやってくれます。 この定義は、 (with-image (imgvar 640 400) ... body ...) というふうに使うことを想定しています (name, width, height等が with-imageへの直接の引数でなく、括弧に入っていることに注意)。 Gaucheでは、matchマクロを使うか、syntax-rulesでパターンマッチ させることになるでしょう。 (define-macro with-image (var&opts . body) (match var&opts ((name width height . opts) (let* ((true-color (get-optional opts #f))) ...)) (else (error ...))) (define-syntax with-image (syntax-rules () (((name width height true-color) . body) ...) (((name width height) . body) (with-image (name width height #f) . body)) ...)) ただ、このような呼び出し形式のマクロはCL文化ではよく見るのですが (CL標準のwith-open-fileなんかもこの形式ですね)、Schemeではあまり 見ませんね。どちらかというと with-* 自体を関数にして、明示的に クロージャを渡す方が好まれるようです。特に、束縛を導入する構文を 増やしたがらないような感じがあります (let類似のものを除く)。 私自身、with-* というマクロをつい書いてしまうことがありますが、 標準との整合性 (with-input-from-file等) を考えると、似た名前で マクロと関数が混在するのは好ましくないと思います。 Gaucheらしい呼び出し形式としては、こんな感じで、procに作られた イメージオブジェクトを渡し、オプショナルなものをキーワードで渡す ようにしたらどうでしょう。call-with-input-file等のAPIと並べてみて 下さい。 (call-with-gd-image width height proc &keyword true-color) なお、&keywordというのはここではAPIを示すのに使っているだけで、 実装では let-keywords* などを使って自分で取り出す必要があります。 --shiro