问题描述
我正在学习Common LISP: A Gentle Introduction to Symbolic computation这本书。这本书大约有 40 年的历史了,显然有点经典。
在第 1 章中,作者使用框来解释具有输入和输出的函数。这是其中一张图:
其实上图就是这个问题的答案。我得到了第一个问题和第二个问题:
(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
。
符号 NIL
和 NIL
之间有什么不同?
-
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)
。