Suppose I got this code segment:
(defparameter *islands* '((1 9 8 5) (6 4 2 3)))
(defun edge-pair (a b)
(unless (eql a b)
(list (cons a b) (cons b a))))
(defun connected-with-bridges (islands)
(when (cdr islands)
(append (edge-pair (caar islands) (caadr islands))
(connected-with-bridges (cdr islands)))))
Now, if I pass in the interpreter (SBCL):
(connected-with-bridges '((1 9 8 5) (6 4 2 3)))
The result is:
((1 . 6) (6 . 1))
It won't crash. However, if I pass in:
;; '(6 4 2 3) is actually (cdr '((1 9 8 5) (6 4 2 3)))
(caar '(6 4 2 3))
It will crash. According to (connected-with-bridges)
function, the cdr of the list *islands*
will be kept passing in until it can not longer proceed. The first time when *islands*
is passed into (connected-with-bridges)
, the list will be '((1 9 8 5) (6 4 2 3)
. However, as the recursion goes, the 2nd time will be '(6 4 2 3)
, which in the (append)
function, it will have:
(append (edge-pair (caar '(6 4 2 3)) (caadr '(6 4 2 3)))
(connected-with-bridges (cdr islands)))
It obviously is crashed if I run it alone in the interpreter, but not with if it is ran inside (append)
, which is inside (connected-with-bridges).
(caar '(6 4 2 3))
signals an error cause you are trying to do (car 6)
, and 6 is not a list.
Inside your function, you dont have (caar '(6 4 2 3)), but(caar '((6 4 2 3)))
.
Look how cdr works:
(cdr '((1 9 8 5) (6 4 2 3))))
=> '((6 4 2 3))
, not '(6 4 2 3)
So...
(caar '((6 4 2 3))) => 6, and (car '(6 4 2 3))
=> 6
Do you see your mistake?