为什么不(申请或[真假])在Clojure工作?

时间:2010-06-03 20:31:48

标签: clojure apply

根据我对apply的理解,它解压缩列表并将元素转换为函数的参数。

我看到(apply + [1 2 3])按预期工作,即:它相当于(+ 1 2 3)。

为什么(apply或[true false])无效?是不是等同于(或真假)?

5 个答案:

答案 0 :(得分:19)

因为or是一个宏,而不是一个普通的函数。您可以使用(some identity [true false])获得相同的效果。

答案 1 :(得分:4)

作为的替代方法,您可以使用(某些谓词coll)。

  

clojure.core / some([pred coll])
  返回第一个逻辑true值   (pred x)对于coll中的任何x,否则   零。一个常见的习语是使用一套   作为预测,例如这将   return:fred if:fred是在   序列,否则为零:(一些#{:fred} coll)

答案 2 :(得分:3)

你可以尝试一些真实的吗?和假?谓词,


user=> (some true? [true false false])
true
user=> (not (some true? [true false false]))
false
user=> (some false? [true false false])
true
user=> (not (some false? [true false false]))
false

答案 3 :(得分:0)

是一个宏,您不能将其用作值。

创建一个匿名函数,通过eval在运行时扩展

(apply #(eval (list* 'or %&)) [true false])

答案 4 :(得分:0)

值得注意的重要事项之一是评估模型。 or短路,因此:(or true :some random expression that never gets evaluated:)永远不会评估最后一次。 or传统上与控制结构一样使用'逻辑或'。

(f x y z)的传统模型中,评估x,y和z,并将f应用于它们。

(apply f vec)的使用中,向量的内容评估,它们按原样进行。使用符号向量可以清楚地看到这一点,它们在此上下文中不会对其绑定进行评估。然而,由于Clojure的矢量创建模型与其他lisps有所不同,[a b c d]生成一个包含符号ab的评估的向量,这一点被混淆了。 cd。对比大多数Lisps,其中#(a b c d)不评估符号,只是与评估(vector 'a 'b 'c 'd)(或实际上(apply vector '(a b c d)))相同。

因此,即使可以应用特殊的句法形式,它的结果也会有不透明的语义。 or首先计算其第一个参数,如果为true,则停止并返回该参数,否则它将转到第二个并重复直到最后一个。在apply的情况下,参数已经全部被评估,如果它然后再评估一次?很可能在此过程中导致运行时错误?

从实现的角度来看,如果语法也是“对象”并且需要更复杂的评估模型,那么它将非常具有性能。所以它们不是在运行时解析,而是在编译时重写为编译器原语。

但是,由于这个原因,当or在逻辑上而不是作为控制结构使用时,我自己发现函数or/fand/f,{{1}很方便等等,可以使用哪些是真正的程序并评估它们的所有参数,因此可以应用。