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

Lisp 为什么使用car和cdr操作检索元素会导致异常,而(append)则不会?,lisp,cdr,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 is

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

(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):

结果是:

((1 . 6) (6 . 1))
它不会崩溃。但是,如果我通过:

;; '(6 4 2 3) is actually (cdr '((1 9 8 5) (6 4 2 3)))
(caar '(6 4 2 3)) 
它会崩溃的。根据
(与网桥连接)
功能,列表
*孤岛*
的cdr将一直传入,直到无法继续。第一次将
*孤岛*
传递到
(与桥连接)
,列表将是
((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)
内部运行(与桥连接),则不会崩溃

不,试试看

(caar '(6 4 2 3) (caadr '(6 4 2 3))
那不是有效的Lisp

Lisp也不会“崩溃”。它只会发出错误信号

SBCL也不是解释器。它使用编译器

不,试试看

(caar '(6 4 2 3) (caadr '(6 4 2 3))
那不是有效的Lisp

Lisp也不会“崩溃”。它只会发出错误信号

SBCL也不是解释器。它使用编译器。

(caar'(6 4 2 3))
发出错误信号,导致您尝试执行
(车6)
,而6不是列表

在函数中,没有(caar’(6423)),而是
(caar’((6423))

看看工作原理:
(cdr'((19 8 5)(6 4 2 3)))
=>
((6 4 2 3))
,而不是
(6 4 2 3)
所以 (caar’((6423))=>6和
(car’(6423))
=>6

你看到你的错误了吗?

(caar'(6 4 2 3))
发出一个错误信号,导致你试图执行
(6号车)
,而6不是一个列表

在函数中,没有(caar’(6423)),而是
(caar’((6423))

看看工作原理:
(cdr'((19 8 5)(6 4 2 3)))
=>
((6 4 2 3))
,而不是
(6 4 2 3)
所以 (caar’((6423))=>6和
(car’(6423))
=>6


你看到你的错误了吗?

我知道它无效,而且应该有错误,因为
(car'(6 4 2 3))
已经返回了6。行
(caar'(6 4 2 3)(caadr'(6 4 2 3))
只是对传递到函数中的内容的解释。也许我应该删除它。但是,如果我将原始孤岛传递到函数中,它将不会有错误,或者即使我将
(6 4 2 3)
传递到(与桥连接),没有错误。关于SBCL,我可以交互的接口叫什么?@Amumu交互的接口叫REPL(read-eval-print-loop)。好的,我明白了。它是'((6 4 2 3)NIL).忘了它。好吧,我正在学习Lisp,所以你应该给出一个直接的答案。我以为你在跟我谈论语法错误。而且,我知道REPL,但它实际上是什么?它对我来说似乎是一个解释器,但实际上不是。它会编译代码,然后将结果返回给我吗?但仍然感谢你的回答。在编译后的Lisp,这正是发生的情况。通常你不必担心REPL上键入的代码是否编译,因为结果是一样的。我知道它无效,应该有错误,因为
(car'(6 4 2 3))
已经返回了6。行
(caar'(6 4 2 3)(caadr'(6 4 2 3))
只是对传递到函数中的内容的解释。也许我应该删除它。但是,如果我将原始孤岛传递到函数中,它将不会有错误,或者即使我将
(6 4 2 3)
传递到(与桥连接),没有错误。关于SBCL,我可以交互的接口叫什么?@Amumu交互的接口叫REPL(read-eval-print-loop)。好的,我明白了。它是'((6 4 2 3)NIL).忘了它。好吧,我正在学习Lisp,所以你应该给出一个直接的答案。我以为你在跟我谈论语法错误。而且,我知道REPL,但它实际上是什么?它对我来说似乎是一个解释器,但实际上不是。它会编译代码,然后将结果返回给我吗?但仍然感谢你的回答。在编译后的Lisp,这正是发生的情况。通常你不必担心在REPL上键入的代码是否编译,因为结果是一样的。阅读我写的:(cdr'((1 9 8 5)(6 4 2 3)))不是(6 4 2 3)。试试看。阅读我写的:(cdr'((1 9 8 5)(6 4 2 3))不是(6 4 2 3)。试试看。啊,我明白了。所以,它是“((6423)),不是“((6423)),所以第三次是(cdr)((6423))是零,它是有效的。我现在明白了。谢谢。抱歉,我刚才回过。啊,我明白了。所以,它是“((6423)),不是“(6423)),所以第三次是(cdr)((6423))是零,它是有效的。我现在明白了。谢谢。很抱歉反应太晚,我刚刚回来。
(caar '(6 4 2 3) (caadr '(6 4 2 3))