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 |

2009-07-19

(SETF NTHCDR)問題

| 22:43 | (SETF NTHCDR)問題 - わだばLisperになる を含むブックマーク はてなブックマーク - (SETF NTHCDR)問題 - わだばLisperになる

(SETF NTHCDR) - kozima の日記 - cadr groupより(SETF NTHCDR)問題

そうなんですよね、nthcdrにsetfフォームがあっても良さそうなんですが、無いんですよね。

kozimaさん:

実際に作ってみようと考える人もそれなりにいると思うので、
探せばコードまたは問題点を指摘した文書が見つかるのではないかと思いますが

去年のNANRIさんのブログで問題提起があってそれからLingrのCommon Lisp部屋で話題になったので記念にログを貼ってみることにしました('-'*)

  • NANRIさん 2008-05-15T03:06:19+09:00

nthcdr のsetf expanderってどう書くんだろって思ったときに疑問に思ったのでした。

n=0のときどう処理させれば良いのか、分からなかった。

  • g000001 2008-05-15T03:08:29+09:00

なるほどー、自分は(setf (last foo) '(x))とかやっていつも怒られますねw

あれ、nthcdrはSBCLでも定義されていないのかー。

...略

  • NANRIさん 2008-05-15T03:14:56+09:00

n>0の時の処理は簡単なんですよね。

...略

  • NANRIさん 2008-05-15T03:16:50+09:00

や、あれであっているかどうかもホントのところはよく分からないのですが。

n=0の時の処理が、イメージできないというか。

  • g000001 2008-05-15T03:18:24+09:00

なるほど、自分勘違いしてましたw

0だとまんまのリストを返すんですよね

  • NANRIさん 2008-05-15T03:18:51+09:00

listを丸ごと置き換えてしまっても良いような気もするし、定義できないような気もして。

  • g000001 2008-05-15T03:19:08+09:00

確かに、どうやるんですかねw

丸ごと置き換えってことになるんでしょうか…。

  • NANRIさん 2008-05-15T03:20:17+09:00

まあ使わなくても他にやりようがあるので困らないんですけど。

...略

  • NANRIさん 2008-05-15T03:27:20+09:00

http://d.hatena.ne.jp/sumim/20060910/p1 setfの歴史で思い出したネタ。

意外なことに、アラン・ケイ発のアイデアなのだそうで

だそうです。

  • g000001 2008-05-15T03:28:16+09:00

リーダーで読み出して来た場所に書き込むっていうアイディアですねー。

  • NANRIさん 2008-05-15T03:30:53+09:00

nth と nthcdr の対応はそんなに変でもない気がしますが、0のときはcdrか?って感じで、変な感じしますね。

...

  • NANRIさん 2008-05-15T03:54:43+09:00

ん~、リスト全体を指しているポインタは変わっていないから、リスト操作はリスト操作なのか

なんか、混乱してきましたw

  • g000001 2008-05-15T03:55:12+09:00

そうですねw

rplacaだと中身だけかえられるかなと思って

rplacaの方が良いのかなと漠然と考えたんですが、厄介ですねw

  • 紆余曲折あってg000001が考えた(setf nthcdr)
(defsetf nthcdr (pos lst) (subst)
  (case pos
    (0 `(progn
          (rplaca ,lst (car ,subst))
          (rplacd ,lst (cdr ,subst))))
    (1 `(rplacd ,lst ,subst))
    (otherwise `(rplacd (nthcdr (1- ,pos) ,lst) ,subst))))

;; もしくは

(defun (setf nthcdr) (subst pos lst)
  (case pos
    (0 (progn
         (rplaca lst (car subst))
         (rplacd lst (cdr subst))))
    (1 (rplacd lst subst))
    (otherwise (rplacd (nthcdr (1- pos) lst) subst))))

大分経ってから再度話題に…

  • onjoさん 2008-07-26T21:49:49+09:00

あれ? (cdr (nthcdr ...)) か (car (nthcdr ...)) だからなくていいのでは?

nthcdrはconsセルを返すから、書き換えるのはcar か cdr => だから setf car と setf cdr があるからおk

当時のまとめ

なるほど、なるほど。確かにconsセルを返す関数があれば、その結果に(setf car)か(setf cdr)すれば、それでOKですよね…という流れでした。