和运营商Lisp

时间:2015-11-22 05:19:48

标签: lisp common-lisp

为什么and运算符返回值?返回的值取决于什么?

当我尝试以下示例时 -

(write (and a b c d)) ; prints the greatest integer among a b c d

其中abcd是正整数,然后and会返回其中最大的整数。

但是,当abcd中的一个为0或负数时,则返回最小的整数。为什么会这样?

2 个答案:

答案 0 :(得分:7)

documentation中所述:

  

and从左到右一次评估每个表单。只要任何表单评估为niland就会返回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))相同。上述规则的效果是,无论我们在这个复合表达式中对这些术语进行分组的方式,xyz从左到右进行评估,并且评估要么在它遇到的第一个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,但我们丢失了可能有用的信息。
  • n-place and的行为是关联属性的结果;或者更确切地说,由于关联属性,保留了平面N-argument形式与所有可能的二进制分组之间的等价性。
  • 所有这一切的一个结果是我们可以有一个扩展的if,如(if cond1 cond2 cond3 cond4 ... condN then-form),其中then-form被评估并在所有条件都为真的情况下产生。我们只需使用if符号拼写and