为什么根据这本书,CL中两个"not"函数的函数组合结果为nil?

Why does the function composition of two "not" functions in CL result in nil according to this book?

我正在学习Common LISP:符号计算的简要介绍这本书。这本书大约有 40 年历史,显然有点经典。

在第 1 章中,作者使用方框来解释具有输入和输出的函数。这是其中一张图:

其实上图就是这个问题的答案。我得到了第一个和第二个问题:

然而,第三个问题似乎很奇怪:

(not(not ...))的组成取决于“...”变量部分。 比如终端显示:

CL-USER> (not (not 12))
T
CL-USER> (not (not nil))
NIL

这本书的练习在某些方面似乎是错误的。但是,由于我对 CL 了解不多,所以我认为最好问问 CL 中更有经验的开发人员是否也认为这是答案中的一个奇怪点 sheet。

我正在使用 SBCL、Slime 和 Common Lisp。我是 CL 的新手,但我在 Racket 方面有一些经验。

提前致谢

这不是作文。这是一个函数调用

(not not)

函数 not 接收一个值作为函数 not 的参数。由于此值不是 NIL,因此 return 值是 NIL:

not:
--------------------
NIL      --->   T           (not NIL)
non-NIL  --->   NIL         (not T), (not 1), (not not), (not (list 1)), ...
--------------------

任何非 NIL 值都是真实的,因此 not return 是 NIL

当然 (not not) 在 Lisp-1 的 Scheme 中工作。在 Lisp-2 的 Common Lisp 中,调用是 (not #'not).

update:实际上调用的是(not 'not),就像书上的例子代码是(not 'fred).

练习没有显示函数的组合;它显示了函数 not 对参数 not 的应用。在 Common Lisp 中,除了 nil(以及 'nil()'())之外的所有值都为真,因此将 not 应用于 not 必须评估为 nil.

有一个警告:not is a function in Common Lisp,但是 CL 中有多个名称空间。如果你想在 REPL 中尝试这个,你必须指定你的意思是 function not,而不是 variable not 通过使用 function#' (尖引号):

CL-USER> (not (function not))
NIL
CL-USER> (not #'not)
NIL
CL-USER> (not not)  ; --> The variable NOT is unbound.

嗯。我们中的一些人懒得实际查找书中的练习;书中的这一点似乎只讨论了数字和符号(呃!)。作者的本意是not是一个符号,也就是说在函数调用中必须要引用

因为 not 是一个 函数 ,它计算它的参数。调用 (not not) 计算参数 not,但 not 是一个未绑定的变量,因此发出错误。要将 符号 not 传递给 函数 not,参数必须用 quote 引用(不是函数,而是特殊运算符quote不计算其参数)或引号(').引用的 not 计算为一个符号:

CL-USER> not  ;  -->  The variable NOT is unbound.
CL-USER> (quote not)
NOT
CL-USER> 'not
NOT
CL-USER> (symbolp 'not)
T
CL-USER> (not 'not)
NIL

由于 nil 是布尔上下文中唯一为假的符号,因此符号 not 必须为真,因此 (not 'not) 必须为假。

练习 1.14:

其实作者是想让我们用符号NOT作为函数NOT的输入。输入不是名为 NOT 的函数,也不是名为 NOT 的变量。因此需要在计算中引用该符号:

> (NOT 'NOT)
NIL

因为每个符号都是 true,所以 true 的不是 falsefalse 在 Common Lisp 中是符号 NIL.

符号 NILNOT 有什么不同?

  • NIL 计算自身
  • NOT 没有默认值并作为变量求值。要对符号 NOT 求值,它需要被引用。

这在旧版本的3.8 使用符号和列表作为数据一章中有解释。