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