3.3.1 Mutable List Structure (pp.252 - 256)
set-car!, set-cdr!の登場。cons cellのcar/cdrを直接書き換えるmutatorですね。*1
実は以前 scale-listあたりで、iterative と recursiveでできあがりのリストの順序のやりやすさをで悩んで、以下のようなことをしていた…ら、実はここのexerciseの内容先取りしてたみたい(ちと違いますが)。
(define (last-cell xs) (if (null? (cdr xs)) xs (last-cell (cdr xs)))) (define (append-element xs x) (set-cdr! (last-cell xs) (cons x ())) xs)
ともかく、!系があればリスト操作はほとんど自由にできるようです。既存のリストを付け変えると、誰も参照していないごみができますが5章でGCをやるのでその時まではヨキに計らってくれている、と思うことにします。
空のペアを返す get-new-pairも紹介。けど、gaucheではUnboundになるような???
Ex.3.12
(cdr x) > (b) (define w (append! x y)) (cdr x) > (b c d)
図は略。
Ex.3.13
+-> |a| |-> |b| |-> |c| | --+ | | +---------------------------+
要するに循環リストで、従ってlast-pair zを評価すると無限ループ。
Ex.3.14
traceかけてみると非常にわかりやすいです。
CALL mystery (a b c d e f) CALL loop (a b c d e f) () CALL loop (b c d e f) (a) CALL loop (c d e f) (b a) CALL loop (d e f) (c b a) CALL loop (e f) (d c b a) RETN loop (f e d c b a) RETN loop (f e d c b a) RETN loop (f e d c b a) RETN loop (f e d c b a) RETN loop (f e d c b a) RETN mystery (f e d c b a)
xをcdrしながらその結果のcdrにset!していってますので、ひっくりかえって順につながるはず。
reverseですね。例によって図は省略。
*1:ところで普通は"!"のことなんて呼んでるんでしょ? 私は(友人の意見ですが)”バン”と呼んでます。