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-01

anaphoric-destructuring-bind改め、with-???

| 01:05 | anaphoric-destructuring-bind改め、with-??? - わだばLisperになる を含むブックマーク はてなブックマーク - anaphoric-destructuring-bind改め、with-??? - わだばLisperになる

前回のエントリでは、anaphoric-destructuring-bindとかいう名前の変なマクロを考えてみたわけなのですが、前に出てきたものを参照してるわけでもなんでもないので、anaphoricというのは変だということに気付きました。

また、使い方もリストに限定されているわけでもないので、destructuring-bindという訳でもないということに気付きました。

とりあえず、変だということは分かったのですが、かといって上手い名前も思い付かず…。

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter *fn*
    '(car cdr rest first second third forth fifth sixth seventh eighth ninth tenth 
      reverse length null)))

(defmacro with-??? (list &body body)
  (let ((xx (mapcar (lambda (x) `(,x (,x ,list))) *fn*)))
    `(symbol-macrolet ,xx
       ,@body)))

;---- 
(let ((foo (list 1 2 3 4)))
  (with-??? foo
    (list :orig foo
          :reverse reverse
          :length length
          :null null)))
;=> (:ORIG (1 2 3 4) :REVERSE (4 3 2 1) :LENGTH 4 :NULL NIL)

;; 適当に何か書いてみる。
(defun encode-direct (coll)
  (with-??? coll
    (if null
        ()
        (labels ((recur (coll tem acc)
                   (with-??? coll
                     (destructuring-bind (cnt item) tem
                       (cond (null (cdr (reverse acc)))
                             ((eql car item)
                              (recur cdr (list (+ 1 cnt) car) acc))
                             (:else
                              (recur cdr 
                                     (list 1 car)
                                     (cons (if (= 1 cnt)
                                               item
                                               tem)
                                           acc))))))))
          (recur (append coll (list (gensym)))
                 (list 1 (gensym))
                 () )))))

(encode-direct '(a a a a b c c a a d e e e e))
;=> ((4 A) B (2 C) (2 A) D (4 E)) 

適当に小物を書いてみたのですが、with-???は、入れ子だと名前が競合して使いにくいことが判明しました。(当然といえば当然なのですが)

(with-??? foo bar ... )とした場合、foo-car、bar-first等で参照できるようにすると解決できそうではありますが、混沌としたものになりそうです…。