为什么and
运算符返回值?返回的值取决于什么?
当我尝试以下示例时 -
(write (and a b c d)) ; prints the greatest integer among a b c d
其中a
,b
,c
和d
是正整数,然后and
会返回其中最大的整数。
但是,当a
,b
,c
和d
中的一个为0或负数时,则返回最小的整数。为什么会这样?
答案 0 :(得分:7)
如documentation中所述:
宏
and
从左到右一次评估每个表单。只要任何表单评估为nil
,and
就会返回nil
而不评估剩余的表单。如果所有形成但最后一个评估为true
值,并返回通过评估最后一个表单生成的结果。如果未提供表单,则(and)
会返回t
。
因此返回的值不依赖于哪个值是参数的“最大”或“最小”。
答案 1 :(得分:2)
and
可视为两地if
的概括。也就是说,(and a b)
的工作原理与(if a b)
完全相同。如果and
代替if
,我们可以添加更多条件:(and a1 a2 a3 a4 ... aN b)
。如果它们都为true,则返回b
。如果我们使用if
来表达这一点,则会更加详细,因为我们仍然必须使用and
:(if (and a1 a2 a3 ... aN) b)
。 and
也可以概括为只能使用一个参数(if
不能),甚至根本没有参数(在这种情况下产生t
)。
数学上,and
形成一个群组。该组的标识元素为t
,这就是(and)
产生t
的原因。为了描述N-argument and
的行为,我们只需要这些规则:
(and) -> yield t
(and x y) -> { if x is true evaluate and yield y
{ otherwise yield nil
现在事实证明,这个两地and
的规则服从联想法:即(and (and x y) z)
的行为方式与(and x (and y z))
相同。上述规则的效果是,无论我们在这个复合表达式中对这些术语进行分组的方式,x
,y
和z
从左到右进行评估,并且评估要么在它遇到的第一个nil
处停止并产生nil
,要么评估结束并产生z
的值。
因此,因为我们有这个很好的关联属性,所以用像Lisp这样不与中缀运算符绑定的好语言做的理性事情就是要认识到,因为关联分组并不重要,所以让&# 39; s只有平坦的语法(and x1 x2 x3 ... xN)
,任意数量的参数包括零。此语法表示N-1
二进制and
的所有可能关联,它们都产生相同的行为。
换句话说,让我们不要让可怜的程序员写一个嵌套的(and (and (and ...) ...) ...)
来表达一个四项and
,然后让他们用四个参数写(and ...)
要点:
and
产生t
,这与t
作为and
操作的标识元素有关。and
会产生第二个值。 如果,这对两地有用。当两个参数都为真时,二进制and
可以定义为产生t
,但这样做不太有用。在Lisp中,任何不是nil
的值都是布尔值true。如果我们用nil
替换非t
值,它仍为布尔值true,但我们丢失了可能有用的信息。and
的行为是关联属性的结果;或者更确切地说,由于关联属性,保留了平面N-argument形式与所有可能的二进制分组之间的等价性。if
,如(if cond1 cond2 cond3 cond4 ... condN then-form)
,其中then-form
被评估并在所有条件都为真的情况下产生。我们只需使用if
符号拼写and
。