Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么';t(应用或[真假])在Clojure工作?_Clojure_Apply - Fatal编程技术网

为什么';t(应用或[真假])在Clojure工作?

为什么';t(应用或[真假])在Clojure工作?,clojure,apply,Clojure,Apply,从我对apply的理解来看,它解压缩了一个列表,并将元素转换为函数的参数 我看到(apply+[1,2,3])按预期工作,即:它相当于(+1,2,3) 那么为什么(apply或[true-false])无效?这不等于(或真或假)吗 因为或是一个宏,而不是一个正常函数。您可以使用(某些标识[true-false])获得相同的效果,作为或的替代方法,您可以使用(some谓词coll) clojure.core/some([pred coll]) 返回第一个逻辑真值 对于coll中的任意x,of(pr

从我对apply的理解来看,它解压缩了一个列表,并将元素转换为函数的参数

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


那么为什么(apply或[true-false])无效?这不等于(或真或假)吗

因为
是一个宏,而不是一个正常函数。您可以使用
(某些标识[true-false])
获得相同的效果,作为的替代方法,您可以使用(some谓词coll)

clojure.core/some([pred coll])
返回第一个逻辑真值 对于coll中的任意x,of(pred x),else 无一个常见的习惯用法是使用集合 例如,作为pred,这将 返回:fred如果:fred在 序列,否则为nil:(some#{:fred}coll)


你可以试试真的吗?那是假的吗?谓词


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

是一个宏,不能用作值

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

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

但需要注意的一个重要事项是评估模型
短路,因此:
(或true:一些从未计算过的随机表达式:)
从未计算过最后一个表达式<代码>或
传统上与“逻辑或”一样用作控制结构

在传统的
(f x y z)
模型中,对x、y和z进行求值,并对其应用f

在使用
(apply f vec)
时,不评估向量的内容,而是按原样处理。这在符号向量中最为明显,它们在此上下文中不会对其绑定求值。然而,Clojure的向量创建模型与其他Lisp有一些不同,这一事实使这一点变得模糊,
[a b c d]
生成一个向量,其中包含符号
a
b
c
d
的求值。与大多数LISP不同的是,
#(abcd)
不计算符号,只是与计算
(vector'abcd'c'd)
(或者实际上是
(apply vector'(abcd))
)相同

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

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


但是,正是由于这个原因,当逻辑上使用
而不是作为一个控制结构时,我自己发现使用函数
或/f
和/f
如果/f
,等等非常方便,这些函数都是真正的过程,可以计算它们的所有参数,因此可以应用。

啊。谢谢你能想出任何替代方案吗?
(减少#(或%1%2)假[真假…)
我一直以为
有些
(comp-first-filter)
我自己,直到Chouser好心地让我看到更复杂的现实。尝试
(some:a[{:a false}{:a nil}{:a true}])
,然后用
(comp first filter)
替换
some
。@Michal:Very good correction。谢谢你帮我澄清。我已经从帖子中删除了这一点,不过我要提醒所有阅读的人,在这种特殊情况下,
一些
相当于
(comp first filter)
——它们都做相同的事情,给出相同的结果。小心错误?!(false?nil)返回false,尽管nil被视为false。(boolean nil)返回false。由于不使用宏(通过执行
(reduce#(或%1%2)false…
)可以更自然地获得相同的结果,因此使用
eval
是一个坏主意。举个例子:您的表单没有做
所做的事情。例如,尝试在向量
['(或)false]
上使用它。