Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2010-10-29

APROGNの実装色々

| 23:53 | APROGNの実装色々 - わだばLisperになる を含むブックマーク はてなブックマーク - APROGNの実装色々 - わだばLisperになる

先日のエントリーでAPROGNというアナフォリックなPROGNを突然定義して使ってみましたが、

(defmacro aprogn% (&body body)
  `(let (it)
     (setq ,@(mapcan (curry #'list 'it)
                     body))
     it))

;; マクロ展開
(aprogn%
  1
  it)
⇒
(LET (IT)
  (SETQ IT 1
        IT IT)
  IT)

みたいな感じでSETQに展開するものでした。

これはこれでOKかなと思いましたが、他にも何パターンか考えてみました。

LETに展開

(defmacro aprogn%% (&body body)
  (if (null body)
      'it
      `(let ((it ,(car body)))
         (aprogn%% ,@(cdr body)))))

;; マクロ展開
(aprogn%%
  1
  2
  3
  it)
⇒
(LET ((IT 1))
  (LET ((IT 2)) 
    (LET ((IT 3))
      (LET ((IT IT)) 
        IT))))

LET*に展開

(defmacro aprogn%%% (&body body)
  `(let* (it
          ,@(mapcar (curry #'list 'it)
              body))
     it))

;; マクロ展開
(aprogn%%%
  1
  2
  3
  it)
⇒
(LET* (IT 
       (IT 1)
       (IT 2)
       (IT 3)
       (IT IT))
  IT)

ITを直前の式で置換

(defmacro aprogn%%%% (&body body)
  (reduce (lambda (ans x)
            (subst ans 'it x :test #'equal))
          body))

;; マクロ展開
(aprogn%%%%
  (write-to-string '([]))
  (ppcre:regex-replace-all "\\[" it "(")
  (ppcre:regex-replace-all "\\]" it ")")
  (read-from-string it))

⇒
(READ-FROM-STRING
 (PPCRE:REGEX-REPLACE-ALL "\\]"
                          (PPCRE:REGEX-REPLACE-ALL "\\[" 
                                                   (WRITE-TO-STRING '([]))
                                                   "(")
                          ")"))

最後のだけ動作が違いますが、やりたいこととしては入れ子を展開することが目的なので、一番あっている気もします。

しかし、これだとPROGNという名前は良くないのかもしれない…。

ゲスト



トラックバック - http://cadr.g.hatena.ne.jp/g000001/20101029