by shigemk2

当面は技術的なことしか書かない

対話によるCommon Lisp入門 34 reverse

因みに、doneは前回の(10000 9999 9998 .... 2 1 0)のクソ長いリストである。
reverseも非破壊的な関数でありコピーしているから、
リストが長大である程処理速度も長くなる。

lst => (A B C D)のときは、

(reverse lst) => (D C B A)
(reverse (rest lst)) (D C B)

故に(D C B)と(A)をappendすればよいわけです。はい。
1. (append (D C B) (A))
2. (append (D C) (list (first (A B))))
みたいに。

[80]> (defun reverse$ (lst)
(if (null lst) nil
(append (reverse$ (rest lst))
(list (first lst)))))
REVERSE$
[81]> (reverse$ done)

*** - Program stack overflow. RESET
[82]> (reverse$ '(3 2 1))
(1 2 3)
[83]> (trace reverse$)
;; Tracing function REVERSE$.
(REVERSE$)
[84]> (reverse$ '(3 2 1))
1. Trace: (REVERSE$ '(3 2 1))
2. Trace: (REVERSE$ '(2 1))
3. Trace: (REVERSE$ '(1))
4. Trace: (REVERSE$ 'NIL)
4. Trace: REVERSE$ ==> NIL
3. Trace: REVERSE$ ==> (1)
2. Trace: REVERSE$ ==> (1 2)
1. Trace: REVERSE$ ==> (1 2 3)
(1 2 3)
[85]> (setf hoge '(1 2 3))
(1 2 3)
[86]> (reverse$ hoge)
1. Trace: (REVERSE$ '(1 2 3))
2. Trace: (REVERSE$ '(2 3))
3. Trace: (REVERSE$ '(3))
4. Trace: (REVERSE$ 'NIL)
4. Trace: REVERSE$ ==> NIL
3. Trace: REVERSE$ ==> (3)
2. Trace: REVERSE$ ==> (3 2)
1. Trace: REVERSE$ ==> (3 2 1)
(3 2 1)
[87]> hoge
(1 2 3)