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))=> 6Do you see your mistake?