和运算符Lisp

和运算符Lisp,lisp,common-lisp,Lisp,Common Lisp,为什么和运算符返回一个值?返回值依赖于什么 当我尝试下面的例子时- (write (and a b c d)) ; prints the greatest integer among a b c d 其中a、b、c和d为正整数,则和返回其中最大的整数 但是,当a、b、c和d中的一个为0或负时,则返回最小的整数。为什么会出现这种情况?如中所述: 宏和从左到右一次计算每个表单。一旦任何表单的计算结果为nil,和将返回nil,而不计算其余表单。如果除最后一个窗体之外的所有窗体都计算为true值,并返

为什么
运算符返回一个值?返回值依赖于什么

当我尝试下面的例子时-

(write (and a b c d)) ; prints the greatest integer among a b c d
其中
a
b
c
d
为正整数,则
返回其中最大的整数

但是,当
a
b
c
d
中的一个为0或负时,则返回最小的整数。为什么会出现这种情况?

如中所述:

从左到右一次计算每个表单。一旦任何表单的计算结果为
nil
将返回
nil
,而不计算其余表单。如果除最后一个窗体之外的所有窗体都计算为
true
值,并返回通过计算最后一个窗体生成的结果。如果没有提供表单,
(and)
返回
t

因此,返回值不取决于哪个值是参数中的“最大”或“最小”。

如中所述:

从左到右一次计算每个表单。一旦任何表单的计算结果为
nil
将返回
nil
,而不计算其余表单。如果除最后一个窗体之外的所有窗体都计算为
true
值,并返回通过计算最后一个窗体生成的结果。如果没有提供表单,
(and)
返回
t


因此,返回的值不取决于哪个值是参数中的“最大”或“最小”。

可以视为两个位置
的泛化,如果
。也就是说,
(和ab)
的工作原理与
(如果ab)
完全相同。用
代替
if
我们可以添加更多条件:
(和a1a2a3a4a4…anb)
。如果它们都为true,则返回
b
。如果我们用
If
来表达这一点,它会更加冗长,因为我们仍然必须使用
(If(和a1a2a3…aN)b)
的推广还在于,它只能与一个参数一起使用(
,如果
不能),甚至完全没有参数(在这种情况下产生
t

在数学上,
构成一个组。该组的标识元素是
t
,这就是
(and)
产生
t
的原因。为了描述N参数
的行为,我们只需要以下规则:

(and) -> yield t

(and x y) -> { if x is true evaluate and yield y
             { otherwise yield nil
现在证明,对于两个位置的
来说,这个规则遵循关联定律:即
(和(和xy)z)
的行为方式与
(和x(和yz))
相同。上述规则的效果是,无论我们以这两种方式中的哪种方式将这个复合表达式中的术语分组,
x
y
、和
z
都是从左到右求值的,求值要么在它遇到的第一个
nil
处停止,要么产生
nil
,否则,它将计算到底,并生成
z
的值

因此,因为我们有这个很好的关联属性,所以在像Lisp这样没有中缀运算符的好语言中,理性的做法是认识到,既然关联分组不重要,让我们只使用平面语法
(和x1 x2 x3…xN)
,任何数量的参数包括零。此语法表示
N-1
二进制
s的任何一种可能关联,它们都产生相同的行为

换句话说,让我们不要让可怜的程序员编写一个嵌套的
(and(and(and)(and…)
)来表示四个术语
,而让他们编写带有四个参数的
(and…

总结:

  • 零位
    产生
    t
    ,这与
    t
    操作的标识元素有关
  • 如果第一个值为真,则两个位置
    将产生第二个值如果,这是两个位置的有用等价物。当两个参数都为真时,二进制
    可以定义为产生
    t
    ,但这不太有用。在Lisp中,任何不是
    nil
    的值都是布尔真值。如果我们将非
    nil
    值替换为
    t
    ,它仍然是布尔值true,但我们已经丢失了潜在的有用信息
  • n位
    的行为是关联属性的结果;或者更确切地说,保持平坦N参数形式和所有可能的二元分组之间的等价性,这些二元分组由于结合性质已经彼此等价
  • 所有这一切的一个结果是,我们可以有一个扩展的
    if
    ,比如
    (if cond1 cond2 cond3 cond4…condN then form)
    ,其中
    那么form
    在所有条件都为真的情况下被计算和生成。我们只需要使用
    符号拼写
    if

可以被视为两个位置的推广
,如果
。也就是说,
(和ab)
的工作原理与
(如果ab)
完全相同。用
代替
if
我们可以添加更多条件:
(和a1a2a3a4a4…anb)
。如果它们都为true,则返回
b
。如果我们用
If
来表达这一点,它会更加冗长,因为我们仍然必须使用
(If(和a1a2a3…aN)b)
的推广还在于,它只能与一个参数一起使用(
,如果
不能),甚至完全没有参数(在这种情况下产生
t

在数学上,
构成一个组。该组的标识元素是
t
,这就是
(and)
产生
t
的原因。描述N参数