0

假设我得到了这个代码段:

(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)。但是,随着递归的进行,第二次将是'(6 4 2 3),在(append)函数中,它将具有:

(append (edge-pair (caar '(6 4 2 3)) (caadr '(6 4 2 3)))
                (connected-with-bridges (cdr islands)))

如果我在解释器中单独运行它显然会崩溃,但如果它在内部运行则不会崩溃,它在(append)内部(连接到桥)。

4

2 回答 2

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) So... (caar '((6 4 2 3))) => 6,和(car '(6 4 2 3))=> 6

你看到你的错误了吗?

于 2012-03-05T19:27:20.670 回答
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 也不是口译员。它使用编译器。

于 2012-03-05T19:02:59.807 回答