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 |

2008-10-28

mapfでonce-only

| 09:34 | mapfでonce-only - わだばLisperになる を含むブックマーク はてなブックマーク - mapfでonce-only - わだばLisperになる

ひょっとして実はmapfならonce-onlyみたいなのは綺麗に書けるんじゃないのか?と思ったので書いてみましたが、別に綺麗に書ける訳ではないようです…。というかloop以上に読み難いかもという。

(defmacro once-only ((&rest vars) &body body)
  (mapf (lambda (&rest arg)
          `(let ,(mapcar #'first arg)
             (with-gensyms ,(mapcar #'second arg)
               `(let (,,@(mapcar #'third arg))
                  ,,@body))))
        (lambda (v &aux (g (gensym)))
          `((,g ,v) ,v `(,,v ,,g)))
        vars))

;; with-gensymsも使わない版
(defmacro once-only ((&rest vars) &body body)
  (mapf (lambda (&rest arg)
          `(let ,(mapcar #'first arg)
             (let ,(mapcar (lambda (x) `(,(second x) (gensym))) arg)
               `(let (,,@(mapcar #'third arg))
                  ,,@body))))
        (lambda (v &aux (g (gensym)))
          `((,g ,v) ,v `(,,v ,,g)))
        vars))

;; 動作
(once-only (a b c)
  `(list ,a ,b ,c))
;->
(LET ((#:G2788 A) (#:G2789 B) (#:G2790 C))
  (LET ((A (GENSYM)) (B (GENSYM)) (C (GENSYM)))
    `(LET ((,A ,#:G2788) (,B ,#:G2789) (,C ,#:G2790))
       (LIST ,A ,B ,C))))