我是lisp的新手,我正在尝试一个简单的检查以查看列表是否为空。出于测试目的,我创建了这个测试函数:
(defun test (list)
(if (null (caddr list))
(make-node 1)
(caddr list)))
如果使用make-node
函数定义为:
(defun make-node (atm)
(cons atm `(`() `())))
运行(make-node 6)
时,我得到:
(6 (QUOTE NIL) (QUOTE NIL))
这就是我想要的。
然后我打电话给(test (make-node 6))
然后我得到:
(QUOTE NIL)
这是来自测试的(caddr list)
。如果你运行(null (QUOTE NIL))
,你得到T
这是我想要的,但是当我从给定的测试函数运行它时,我会收到NIL
。
所以我的问题是为什么当我检查这是否为空时为什么我会NIL
而不是T
?
答案 0 :(得分:3)
评估(null (quote nil))
时,会评估(quote nil)
,导致nil
被用作函数null
的参数。
但是,当您评估(null (function-returning-quote-nil))
之类的内容时,会对function-returning-quote-nil
进行评估,从而生成列表(quote nil)
,然后将其用作函数null
的参数,而无需进一步评估
比较
之间的区别 (null (quote nil)) ; => t
和
(null '(quote nil)) ; => nil
答案 1 :(得分:2)
(CADDR '(6 (QUOTE NIL) (QUOTE NIL))) ; ==> (QUOTE NIL) or just 'NIL
包含QUOTE
和NIL
两个符号的列表不等于NIL
。只有NIL
等于NIL
。例如。
(DEFPARAMETER TEST 'NIL)
TEST ; ==> NIL
(NULL TEST) ; ==> T
这是有效的,因为'NIL被评估为NIL并分配给TEST。 TEST被评估为NIL并且它是CLs NULL值。但是:
(DEFPARAMETER TEST2 ''NIL)
TEST2 ; ==> 'NIL or (QUOTE NIL)
(NULL TEST2) ; ==> NIL
包含两个元素QUOTE和NIL的列表,显着为'NIL
,不是NIL
。只有NIL
为NIL
。
修改强>
在查看有关取消引用的评论后,我很确定您希望将其作为make-node
:
(defun make-node (atm)
(cons atm '(() ())))
(test (make-node 6)) ; ==> (1 NIL NIL)
在数据结构中没有unquoting这样的东西,除非你真的想在你的数据中使用符号quote
,否则引用内容中的引号是没有意义的。 (因为存在一半的事实,但它涉及到宏)