読者です 読者をやめる 読者になる 読者になる

xyzzy lispで簡易destructuring-bind

sbclでdestructuring-bindをmacroexpand-1した結果を見てみて、なんとなくやってる事がわかった気がしたので&keyや&wholeを省いた簡単なものを自前で書いてみた。

(defmacro simple-dbind (varlist valuelist &body body)
  (let ((whole (gensym))
        binds)
    (labels ((rec (vars acc)
               (cond
                ((null vars) binds)
                ((atom vars) (push (list vars acc) binds))
                ((consp vars)
                 (rec (car vars) `(car ,acc))
                 (rec (cdr vars) `(cdr ,acc))))))
      `(let ((,whole ,valuelist))
         (let ,(reverse (rec varlist whole)) ,@body)))))

xyzzyで実行

(simple-dbind (a ((b . c) d) e . f) '(1 ((2 3) 4) 5 6 7)
  (list a b c d e f))

=> (1 2 (3) 4 5 (6 7))

macroexpand-1結果

(let ((#1=#:G765 '(1 ((2 3) 4) 5 6 7)))
  (let ((a (car #1#))
        (b (car #2=(car #3=(car #4=(cdr #1#)))))
        (c (cdr #2#))
        (d (car (cdr #3#)))
        (e (car #5=(cdr #4#)))
        (f (cdr #5#)))
    (list a b c d e f)))

どんな穴があるか良くわからないけどとりあえず想定どおり動いた。
キーワード引数の受け方も考えてみよう。