Hatena::Groupcadr

kozima の日記

2009-07-19

続 (SETF NTHCDR)

| 23:50

昨日数時間前に書いた

(if (plusp n)
    (setf (cdr (nthcdr (1- n) foo)) 'bar)
    (setf foo 'bar))

この展開形、何となく変だなーという気がしてきました。

もう一度考えてみたところ、これだとマクロ展開時に (setf foo 'bar) を展開します。ということは、foo に setf method が必要ですね。例え n > 0 だとわかっていても。

(nthcdr の引数としての) foo のところには任意の式を書けるはずなのに、上のように展開することにすると foo が任意の式になれない。変な気がするのはこれが理由かな、と思います。

(SETF NTHCDR)

| 19:48

nthcdr に setf したいことはときどきあるんですが、標準ではできません。

で、作ろうとするとまず考えることは

(setf (cdr (nthcdr (1- n) foo)) 'bar)

みたいに展開すればいいのかなということなんですが、こうすると n=0 のときに困ります。*1

より意図に近いコードはおそらく

(if (plusp n)
    (setf (cdr (nthcdr (1- n) foo)) 'bar)
    (setf foo 'bar))

だと思うので、こんなふうに展開されるようにすればいいような気もしますが、どうなのでしょう。これくらいのことを思いつく人はたくさんいそうで、その中には実際に作ってみようと考える人もそれなりにいると思うので、探せばコードまたは問題点を指摘した文書が見つかるのではないかと思いますが。

*1:だから setf method がないのかなあと思ったことがあります