#:g1: (declare (ignore ignore))が面倒

Posted 2009-02-09 06:20:00 GMT

最近は専らClozure CLばかり使っているのですが、ふとしたきっかけから

(declaim (ignore ignore))
が動くことを知りました。
これで、大域的にdeclaimや、proclaimで変数ignoreを無視する宣言ができたら
(let ((foo '(a b c d e f g)))
    (mapcar (lambda (ignore) (gensym))
            foo))
などでもLAMBDAのところにdeclareを入れなくて済むのでイイ! などと思っていたのですが、SBCLにしたら普通に警告がでたので、HyperSpecで調べたら、どうもdeclaim/proclaimでignoreが使えるのは、Clozure CLの拡張のようです。
そうなると、やっぱりマクロしかないかということで、ちょっと工夫したマクロを考えてみました。
ちょっとの工夫とは、変数にインターンされない変数を利用した場合は、自動的にそれが無視リストに加えられるというものです。

名前はともかくとして、インターンされない変数名を利用すると同じ名前が並べられるので割と使い勝手は良いかもと思いました。
igmultiple-value-bindなどの派生も考えられます。
(defmacro iglambda ((&rest bvl-spec) &body body)
  (let ((ignores (remove-if #'symbol-package bvl-spec)))
    `(lambda ,bvl-spec 
       (declare (ignore ,@ignores))
       ,@body)))
(let ((foo '(a b c d e f g)))
  (mapcar (iglambda (#:ignore #:ignore) (gensym))
          foo
          foo))
;=> (G2742 G2743 G2744 G2745 G2746 G2747 G2748) 

(funcall (iglambda (#:x) (print "foo")) 33) ;-> "foo" ;=> "foo"


comments powered by Disqus