[Gauche-devel-jp] Re: CommonLisp の defmacro の &body 相当について

アーカイブの一覧に戻る

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





Gauche-devel-jp メーリングリストの案内
アーカイブの一覧に戻る