为什么根据这本书,CL中两个“非”函数的函数组合会导致nil?

问题描述

我正在学习Common LISP: A Gentle Introduction to Symbolic computation这本书。这本书大约有 40 年的历史了,显然有点经典。

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

enter image description here

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

enter image description here

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

enter image description here

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

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

这本书的练习在某种程度上似乎是错误的。但是,由于我对 CL 不太了解,我想最好问问更有经验的 CL 开发人员是否也认为这是答卷中的一个奇怪点。

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

提前致谢

解决方法

练习 1.14:

实际上作者希望我们使用符号 Price 作为函数 NOT 的输入。输入不是名为 NOT 的函数,也不是名为 NOT 的变量。因此需要在计算中引用符号:

NOT

因为每个符号都是,不是就是false 在 Common Lisp 中是符号 > (NOT 'NOT) NIL

符号 NILNIL 之间有什么不同?

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

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

,

练习没有显示函数的组合;它显示了函数 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) 必须为假。

,

这不是一个组合。这是一个函数调用

&'a [u8]

函数 (not not) 接收一个值,即函数 not,作为它的参数。由于此值不是 not,因此返回值为 NIL

NIL

任何非 not: -------------------- NIL ---> T (not NIL) non-NIL ---> NIL (not T),(not 1),(not not),(not (list 1)),... -------------------- 值都是真值,因此 NIL 为其返回 not

当然 NIL 可以在 Lisp-1 的 Scheme 中工作。在 Lisp-2 的 Common Lisp 中,调用是 (not not)

更新:调用实际上是(not #'not),正如书中前面示例的代码是(not 'not)