Предположим, я получил этот сегмент кода:
(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)))))
Теперь, если я передам переводчик (SBCL):
(connected-with-bridges '((1 9 8 5) (6 4 2 3)))
Результат:
((1 . 6) (6 . 1))
Это не сломается. Однако, если я передам:
;; '(6 4 2 3) is actually (cdr '((1 9 8 5) (6 4 2 3)))
(caar '(6 4 2 3))
Это потерпит крах. Согласно функции (connected-with-bridges)
, cdr списка *islands*
будет продолжать передаваться до тех пор, пока он не сможет продолжить работу. В первый раз, когда *islands*
передается в (connected-with-bridges)
, список будет '((1 9 8 5) (6 4 2 3)
. Однако, когда идет рекурсия, во 2-й раз будет '(6 4 2 3)
, что в функции (append)
будет иметь:
(append (edge-pair (caar '(6 4 2 3)) (caadr '(6 4 2 3)))
(connected-with-bridges (cdr islands)))
Очевидно, что он выходит из строя, если я запускаю его один в интерпретаторе, но не в том случае, если он запускается внутри (append)
, который находится внутри (связан с мостами).