假设我有这段代码:
(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))
会崩溃。根据{{1}}函数,列表(connected-with-bridges)
的cdr将保持传递,直到它不再继续。 *islands*
第一次传入*islands*
时,列表将为(connected-with-bridges)
。但是,随着递归的进行,第二次将是'((1 9 8 5) (6 4 2 3)
,在'(6 4 2 3)
函数中,它将具有:{/ p>
(append)
如果我在解释器中单独运行它显然会崩溃,但如果它是在(append (edge-pair (caar '(6 4 2 3)) (caadr '(6 4 2 3)))
(connected-with-bridges (cdr islands)))
里面运行的话,它就在内部(与桥连接)。
答案 0 :(得分:2)
;; '(6 4 2 3) is actually (cdr '((1 9 8 5) (6 4 2 3)))
没有。试试吧。
(caar '(6 4 2 3) (caadr '(6 4 2 3))
这不是有效的Lisp。
Lisp也不会“崩溃”。它只会发出错误信号。
SBCL也不是翻译。它使用编译器。
答案 1 :(得分:2)
(caar '(6 4 2 3))
表示您尝试执行(car 6)
时出错,而6不是列表。
在你的功能中,你没有(caar'(6 4 2 3)),但是(caar '((6 4 2 3)))
。
了解cdr的工作原理:
(cdr '((1 9 8 5) (6 4 2 3))))
=> '((6 4 2 3))
,而非'(6 4 2 3)
所以...
(caar'((6 4 2 3)))=> 6,(car '(6 4 2 3))
=> 6
你看到了你的错误吗?