5

多くの言語では、

if (foo() || bar() || foobar()) { /* do stuff */ }

foo()がtrueを返す場合、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も評価されますか、それとも無視されますか?

ありがとう!

4

6 に答える 6

13

あなたはあなた自身の質問に答えたので、あなたの例ではbとcは(またはabc)呼び出しで評価されないかもしれませんが、letバインディングはその前に評価されるので、あまりにも怠惰で最適化するこの関数呼び出しが評価されることに注意してくださいとりあえず。Clojureはそれほど怠惰ではありません。

or明確にするために:関数呼び出しを条件付きで評価するには、基本的に、関数呼び出しを評価する式を呼び出しに入れる必要があります。

(or (simple-function args)
    (complex-function args)
    (too-lazy-to-optimize-this-function args))
于 2011-11-18T23:50:47.753 に答える
11

他の答えはすべて良いですが、疑わしい場合は、いつでもREPLでテストできます。

user=> (or true (do (println "hello") true))
true
user=> (or false (do (println "hello") true))
hello
true
于 2011-11-19T02:05:53.330 に答える
4

疑問がある場合は、ドキュメントを参照してください。

または
マクロ
使用法:

   (or)  
   (or x)  
   (or x & next)  

exprsを左から右に一度に1つずつ評価します。フォームが論理的な真の値を返す場合、またはその値を返し、他の式を評価しない場合は、最後の式の値を返します。(または)nilを返します。

(エンファシスマイン。)

ドキュメントandは、それが同じように動作することを示しています。

于 2011-11-18T23:32:19.690 に答える
1

この質問の入力を終えるとすぐに、「または」のドキュメントを見ることができることに気付きました。

ドキュメントから:「exprsを左から右に一度に1つずつ評価します。フォームが論理的な真の値を返す場合、またはその値を返し、他の式を評価しない場合は、最後の式の値を返します。 。(または)nilを返します。」

于 2011-11-18T23:30:48.340 に答える
1

はい、Clojureには確かに短絡評価があります。

Clojure /その他のLispの興味深い機能の1つは、短絡評価も提供する新しい構造で言語を拡張することもできることです。関数を呼び出す前に関数のすべてのパラメーターを評価する必要があるため、他のほとんどの言語の関数を使用してこれを行うことはできません。

Clojureで短絡NAND関数を実装するマクロの例を次に示します。

(defmacro nand 
  ([x] 
    `(not ~x))              ; NAND is equivalent to NOT for one argument
  ([x & xs] 
    `(let [nand# (not ~x)]
       (if nand# 
         true               ; short circuit if we can prove the nand is true
         (nand ~@xs)))))    ; continue with the other expressions otherwise

(nand true true)
=> false

(nand false (println "Expression with a side effect!"))
=> true
于 2011-11-21T02:44:36.337 に答える
0
if (foo() || bar() || foobar()) { /* do stuff */ }

(if (or (foo) (bar) (boobar)) (comment do stuff))

また

(when (or (foo) (bar) (boobar)) (comment do stuff))
于 2011-11-18T23:50:38.370 に答える