在公共Lisp中,NULL和NIL之间的确切区别是什么?

在公共Lisp中,NULL和NIL之间的确切区别是什么?,lisp,common-lisp,null,Lisp,Common Lisp,Null,据我所知,NIL是许多事物的符号:空列表或布尔值false。到目前为止还不错,但是为什么有时候输出中会出现NULL呢 clisp> (type-of NIL) NULL clisp> (type-of t) BOOLEAN clisp> (type-of (not t)) NULL clisp> NIL NIL clisp> (eq NULL NIL) ERROR.. 所以NULL不是一个定义符号,因为“BASIC-STRING-6”也不是一个。但是我有点被术语N

据我所知,NIL是许多事物的符号:空列表或布尔值false。到目前为止还不错,但是为什么有时候输出中会出现NULL呢

clisp> (type-of NIL)
NULL
clisp> (type-of t)
BOOLEAN
clisp> (type-of (not t))
NULL
clisp> NIL
NIL
clisp> (eq NULL NIL)
ERROR..

所以NULL不是一个定义符号,因为
“BASIC-STRING-6”
也不是一个。但是我有点被术语NULL搞糊涂了,因为不管它是否被否定,布尔值应该仍然是布尔值。

你可能会觉得奇怪,
T
是布尔值,而
NIL
不是。原因是
NIL
有几个帽子。这是一个空列表,它是符号NIL,它是布尔值false。因此,它有时出现在不适合布尔类型值的上下文中,因此从类型安全的角度来看,布尔类型不适合它。类似地,在Scheme中boolean false与空列表不同

NULL作为
NIL
类型

NIL
是在公共Lisp中表示NULL的符号。它也是空列表的表示形式
()
#'NULL
是检查变量是否为NULL的函数(即
eq
NIL

如果要使用NULL而不是NIL,可以定义NULL。(实际上,这可能是一个糟糕的想法。)


确切的区别在于NULL是上下文中的一种类型,而NIL是一种符号

NULL是仅包含符号NIL的类型

类型为NIL的对象是空类型(没有类型为NIL的对象):


NIL作为一个对象是代表各种“非”事物的符号。

NIL
是一个符号。它也写为
()
类型的输出在这里不一定有用。HyperSpec说:

返回对象为的类型的类型说明符typespec 元素

但给定类型层次结构以及通用类型(所有类型都是
t
),类型的输出可能没有帮助。如果你想知道某物是否有特定的类型,这里更有用的是什么。使用typep,我们可以看到,无论什么类型的告诉我们,
nil
是一个布尔值,是一个符号,是一个列表,是一个空值。另一方面,t是一个符号,一个布尔值,不是列表,也不是空值

CL-USER> (type-of nil)
NULL
CL-USER> (type-of t)
BOOLEAN
CL-USER> (typep nil 'boolean)   ; both are booleans
T
CL-USER> (typep t 'boolean)
T
CL-USER> (typep nil 'symbol)    ; both are symbols
T
CL-USER> (typep t 'symbol)
T
CL-USER> (typep nil 'list)      ; only nil is a list
T
CL-USER> (typep t 'list)
NIL
CL-USER> (typep nil 'null)      ; only nil is a null
T
CL-USER> (typep t 'null)
NIL

整数、(数组*)、(成员T NIL)等类型指示符的计算结果不是值。因此,如果您尝试对类型名称NULL求值,那么类型名称NULL会引发错误也就不足为奇了。回想一下,类型/子类型层次结构不是一个简单的树,因此NULL是许多事物的子类型;CONS、BOOLEAN、LIST等

请注意,许多不是布尔类型的事物被视为true。BOOLEAN只是“(成员nil t)的简写形式。所以(type'foo'(成员nilt))与(type'foo'boolean)相等

在学习曲线的这一点上,有必要记住公共Lisp是动态类型的,类型声明更倾向于文档化,并建议编译器的优化器和警告子系统可以接受或忽略哪些

NULL也是一个函数。检查手册的索引可能会对您有所帮助

所以NULL不是一个定义符号,因为“BASIC-STRING-6”也不是一个

NULL
是一个符号。它没有价值。符号
NULL
是类型和函数的名称
NULL
作为一个类型有一个元素:
NIL


NIL
是一个符号,
NIL
是它的值。因此,
NIL
是一个常数,它本身就是一个值
NIL
也是一种类型,一种没有对象的空类型。

最有助于我理解的是,NIL实际上只是一个符号,但却是一个非常特殊的符号。虽然可以定义
null
,但这可能不是一个好主意,因为它会导致单一的代码,让人措手不及。“你可能会认为T是布尔值而NIL不是很奇怪。”除了NIL是布尔值,如
(typep NIL'布尔值)=>T
确认。@JoshuaTaylor CL中的每个对象都是布尔值。当我写这篇文章时,我写的是OP使用
类型的
所经历的。因此是最具体的类型。还要注意@osa在我一年多前写了这篇文章后编辑了它。是和否……我理解你的意思,但为了那些发现这篇文章的经验较少的读者问题,该类型仅包含符号t和nil。但所有内容都是a,并且大多数运算符都接受广义布尔值。请尝试
(大象的类型)
(大象的类型)(不是大象的类型)
t
恰好是布尔值的事实是偶然的。
CL-USER> (type-of nil)
NULL
CL-USER> (type-of t)
BOOLEAN
CL-USER> (typep nil 'boolean)   ; both are booleans
T
CL-USER> (typep t 'boolean)
T
CL-USER> (typep nil 'symbol)    ; both are symbols
T
CL-USER> (typep t 'symbol)
T
CL-USER> (typep nil 'list)      ; only nil is a list
T
CL-USER> (typep t 'list)
NIL
CL-USER> (typep nil 'null)      ; only nil is a null
T
CL-USER> (typep t 'null)
NIL