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-09-30

anaphoric-destructuring-bind

| 18:02 | anaphoric-destructuring-bind - わだばLisperになる を含むブックマーク はてなブックマーク - anaphoric-destructuring-bind - わだばLisperになる

quekさん作のwith-car/cdrは、非常にLISP2の特長が生かせた、自分のお気に入りのマクロの一つです。

(with-car/cdr '(1 2 3 4)
  (list car cdr))
;=> (1 (2 3 4))

この路線で行くところまで行くとすると、アナフォリックなdestructuring-bindだろう!、ということで色々考えていたのですが、こういう場合、symbol-macroletを使えば、簡単に作れる気がしたので作ってみました。

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defvar *anaphoras*
    '(car cdr rest first second third forth fifth sixth seventh eighth ninth tenth)))

(defmacro anaphoric-destructuring-bind (list &body body)
  (let ((anaphoras (mapcar (lambda (x) `(,x (,x ,list))) *anaphoras*)))
    `(symbol-macrolet ,anaphoras
       ,@body)))

(let ((foo (list 1 2 3 4)))
  (anaphoric-destructuring-bind foo
    (list (car foo)
          (funcall #'car cdr)
          cdr
          first
          second
          (setq car 'alt)
          foo)))
;=> (1 2 (2 3 4) 1 2 ALT (ALT 2 3 4))