まくろちゃれんじ!setf編(中)

色々工夫してみた結果、少しマシになった*1

(defmacro my-setf
  (obj val)
  (if (symbolp '(eval obj))
      `(setq ,obj ,val)
      `(progn
         (rplaca ,obj ,val)
         ,val)))

が、これまで無視していた問題が顕れた!

> (macroexpand-1 '(my-setf (car x) 344))
(progn (rplaca (car x) 344) 344)

うげ。
(car x)がxに変わればそのまま使えるけれど、しかし例えばcadrとかcaddrとかそう言ったものにもsetfは使えるわけだから、完全に考え直しが必要そう。
そういうわけで試してみた:

> (macroexpand-1 '(setf (caddr x) 344))
(progn (rplaca (cddr x) 344) 344)
t

> (macroexpand-1 '(setf (cadr x) 344))
(progn (rplaca (cdr x) 344) 344)
t

> (macroexpand-1 '(setf (car x) 344))
(progn (rplaca x 344) 344)
t

> (macroexpand-1 '(caddr x))
(caddr x)
nil

…参った。caddrはマクロではないので、正統に(caddr x)を(cddr x)に変換する方法を考えないといけない。
それ以上に、(car x)をxに変換する手段が見当が付かない。


とりあえず寝よ。

*1:ちゃんと動かないのは仕様