为什么使用car和cdr操作检索元素会导致异常而(append)不是?

时间:2012-03-05 18:54:52

标签: lisp cdr

假设我有这段代码:

(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))) 里面运行的话,它就在内部(与桥连接)。

2 个答案:

答案 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

你看到了你的错误吗?