Clojure 有短路逻辑吗?
在许多语言中,如果您按照 foo() 返回 true 的方式编写某些内容
if (foo() || bar() || foobar()) { /* do stuff */ }
,则不会评估 bar() 和 foobar() 。
假设我有以下 Clojure 代码:
(let [a (simple-function args)
b (complex-function args)
c (too-lazy-to-optimize-this-function args)]
(or a b c))
如果 a 计算结果为 true,b 和 c 也会被计算,还是会被忽略?
谢谢!
In many languages, if you write something along the lines of
if (foo() || bar() || foobar()) { /* do stuff */ }
and foo() returns true, then bar() and foobar() will not be evaluated.
Suppose I had the following Clojure code:
(let [a (simple-function args)
b (complex-function args)
c (too-lazy-to-optimize-this-function args)]
(or a b c))
If a evaluates to true, will b and c also be evaluated, or will they be ignored?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
既然您回答了自己的问题,请注意,尽管在您的示例中 b 和 c 可能不会在 (或 abc) 调用中求值,但 let 绑定会在此之前求值,因此会求值“too-lazy-to-optimize-this-function”调用反正。 Clojure 并不那么懒惰。
需要明确的是:要有条件地评估函数调用,您需要将评估它们的表达式放在
or
调用中,基本上:Since you answered your own question, note that though in your example b and c may not evaluated in the (or a b c) call, the let binding is evaluated before that so the too-lazy-to-optimize-this-function call is evaluated anyway. Clojure isn't as lazy as that.
To be clear: to conditionally evaluate the function calls, you need to put the expression evaluating them in the
or
call, basically:其他答案都很好,但是当有疑问时,您可以随时在 REPL 上进行测试:
The other answers all good, but when in doubt, you can always just test it out on the REPL:
如有疑问,请参阅文档:
(强调我的。)
和<的文档/code>
显示它的行为方式也相同。
When in doubt, consult the documentation:
(Emphasis mine.)
The documentation for
and
shows it behaves in the equivalent way too.当我输入完这个问题后,我意识到我可以只查看“或”的文档。
来自文档:
“从左到右一次评估一个表达式。如果一个表格
返回逻辑真值,或者返回该值但不返回
评估任何其他表达式,否则返回
最后一个表达式的值。 (或)返回零。”
As soon as I finished typing this question, I realized I could just look at the documentation for 'or'.
From the docs:
"Evaluates exprs one at a time, from left to right. If a form
returns a logical true value, or returns that value and doesn't
evaluate any of the other expressions, otherwise it returns the
value of the last expression. (or) returns nil."
是的,Clojure 确实有短路评估。
Clojure/其他 Lisp 中的一个有趣功能是,还可以使用还提供短路评估的新结构来扩展语言。使用大多数其他语言中的函数无法完成此操作,因为必须在调用函数之前评估函数的所有参数。
下面是在 Clojure 中实现短路 NAND 函数的宏示例:
Yes, Clojure does indeed have short circuit evaluation.
One interesting feature in Clojure / other Lisps is that it is also possible to extend the language with new constructs that also provide short-circuit evaluation. This can't be done using functions in most other languages since all the parameters to a function must be evaluated before the function is called.
Here's an example of a macro to implement a short-circuiting NAND function in Clojure:
到
或
to
or