appendによるconsセル操作方法

appendは新しくコピーをつくるイメージがあったけれど,どうやら第1引数のリストはコピーして,最後のcdrに2引数の先頭へのポインタを格納する省コスト操作をしているらしい.

Emacs Lispではそうらしいけれど,Common Lispではどうかな?Xyzzyでちょっと確認.

(setq A '(1 2 3))
(setq B '(4 5 6))
(setq C (append A B)) ; => (1 2 3 4 5 6)

; Aを変更してもCに影響は受けない
(setf (car A) 9)      ; => 9
A                     ; => (9 2 3)
C                     ; => (1 2 3 4 5 6)

; Bのリストは共有しているため,変更するとCに影響を与える
(setf (car B) 8)      ; => 8
C                     ; => (1 2 3 8 5 6)

おぉ,本当だ!

参考

リスト遊び―Emacsで学ぶLispの世界 (ASCII SOFTWARE SCIENCE Language)

リスト遊び―Emacsで学ぶLispの世界 (ASCII SOFTWARE SCIENCE Language)