Exercise 24 [難易度 2]
setcar, setcdrというキーワードを追加し,
Exercise 17 で導入したリスト構造の先頭要素(car)と後続部分
(cdr)の値を更新できるようにインタプリタを変更せよ. (注意: この問題
は, Exercise 18のようにリストをペア構造として扱う方が遥か
に見通しがよいので, Exercise 18 を行なってから解答した方
がよい.)
setcarは引数として二つの式をうけとり, 代入のように,
副作用として第一式が示すリストの先頭要素を第二式が示す値で置き換える.
同様に, setcdrは引数として二つの式をうけとり,
第一式が示すリストの後続要素を第二式が示すリストで置き換える.
返り値については特に限定しない (代入のときを参考にせよ).
⇒ (let ((xs (list 0 2 3 4)))
(let ((d (setcar xs 1)))
xs))
(1 2 3 4)
⇒ (let ((xs (list 0 1 3 4)))
(let ((d (setcdr (cdr xs) (list 2 3 4))))
xs))
(0 1 2 3 4)
setcar, setcdrは,
Exercise 18のようにリストをペア構造としてみれば,
⇒ (let ((p (cons 0 2)))
(let ((d (setcar p 1)))
p))
(1 . 2)
⇒ (let ((p (list 0 1 2)))
(let ((d (setcdr p 4)))
p))
(0 . 4)
のように, それぞれペアの第一要素, 第二要素を置き換えるものとして実現できる.
setcar, setcdrを用いたプログラムを書いてテストせよ.
⇒ (let ((xs (list 1 3 4 5)))
(let ((d (setcdr xs (cons 2 (cdr xs)))))
xs))
(1 2 3 4 5)
⇒(letrec ((nconc (lambda (xs ys)
(if (null xs) ys
(if (null (cdr xs)) (setcdr xs ys)
(nconc (cdr xs) ys))))))
(let ((a (list 0 1 2))
(b (list 3 4 5)))
(let ((d (nconc a b)))
a)))
(0 1 2 3 4 5)