2011-11-18 18 views
5

कई भाषाओं में, आप) सच है, तो बार()क्या क्लोजर में शॉर्ट सर्किट तर्क है?

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

और foo (की तर्ज पर कुछ वापस आती है और foobar() का मूल्यांकन नहीं किया जाएगा बारे में है।

मान लीजिए मैं निम्नलिखित Clojure कोड था: सही करने के लिए एक मूल्यांकन करता है, ख और भी मूल्यांकन किया जा c, या वे अनदेखा कर दिया जाएगा

(let [a (simple-function args) 
     b (complex-function args) 
     c (too-lazy-to-optimize-this-function args)] 
    (or a b c)) 

?

धन्यवाद!

उत्तर

12

के बाद से आप अपने खुद के सवाल का जवाब करने के लिए, ध्यान दें कि हालांकि अपने उदाहरण बी और सी में (या एबीसी) कॉल में मूल्यांकन नहीं कर सकते चलो बाध्यकारी का मूल्यांकन इससे पहले किया जाता है ताकि बहुत आलसी-से-अनुकूलन-इस-फ़ंक्शन कॉल का मूल्यांकन किया जा सके। क्लोजर उस के रूप में आलसी नहीं है।

स्पष्ट है: सशर्त फ़ंक्शन कॉल का मूल्यांकन करने के लिए, आप, अभिव्यक्ति उन्हें or कॉल में मूल्यांकन कर लगाने की जरूरत है मूल रूप से:

(or (simple-function args) 
    (complex-function args) 
    (too-lazy-to-optimize-this-function args)) 
+0

मैं इस एक को स्वीकार कर रहा हूँ, क्योंकि यह पकड़ लिया है कि मैं अनजान था चर्चा करता है। – Joel

+4

यह गॉचा नहीं है, बल्कि आपको समझना होगा कि सब कुछ आलसी अनुक्रमों को छोड़कर और उन कार्यों पर काम करने के लिए उत्सुक है। 'या' शॉर्ट-सर्किट्स मैक्रो के बाद से, यह http://bit.ly/u8xnms तक फैलता है। यदि यह एक समारोह था, तो यह इसके तर्कों का मूल्यांकन करेगा। इसके बजाए, यह एक मैक के लिए macroexpands, जो एक विशेष रूप और शॉर्ट सर्किट है। – gtrak

1

जैसे ही मैंने इस प्रश्न को टाइप करना समाप्त किया, मुझे एहसास हुआ कि मैं केवल 'या' के लिए प्रलेखन देख सकता हूं।

डॉक्स से: "exprs एक समय में एक का मूल्यांकन करता है, बाएं से दाएं एक रूप यह एक तार्किक सही मूल्य देता है, तो या कि मान देता है और अन्य भाव से किसी का मूल्यांकन नहीं करता है, अन्यथा। अंतिम अभिव्यक्ति के मान देता है। (या) शून्य देता है। "

4

संदेह होने पर, परामर्श the documentation:

या
मैक्रो
उपयोग:

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

, exprs एक मूल्यांकन करता है एक समय में बाएं से दाएं। यदि कोई फॉर्म एक तार्किक सत्य मान देता है, या उस मान को देता है और अन्य अभिव्यक्तियों का मूल्यांकन का मूल्यांकन करता है, अन्यथा यह अंतिम अभिव्यक्ति के मान देता है। (या) शून्य वापस आता है।

(जोर मेरा।)

documentation for and यह बराबर रास्ते में भी बर्ताव करता है पता चलता है।

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

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

या

(when (or (foo) (bar) (boobar)) (comment do stuff)) 
10

अन्य उत्तर सब अच्छा है, लेकिन जब संदेह में, आप कर सकते हैं हमेशा आरईपीएल पर इसका परीक्षण करें:

user=> (or true (do (println "hello") true)) 
true 
user=> (or false (do (println "hello") true)) 
hello 
true 
+0

+1 बताए जाने के बजाए प्रदर्शित करने के लिए +1! – mikera

1

हां, क्लोजर में वास्तव में शॉर्ट सर्किट मूल्यांकन होता है।

क्लोजर/अन्य लिस्पस में एक दिलचस्प विशेषता यह है कि नई संरचनाओं के साथ भाषा का विस्तार करना भी संभव है जो शॉर्ट-सर्किट मूल्यांकन भी प्रदान करता है। यह अधिकांश अन्य भाषाओं में फ़ंक्शंस का उपयोग करके नहीं किया जा सकता है क्योंकि किसी फ़ंक्शन के सभी पैरामीटर को फ़ंक्शन कहने से पहले मूल्यांकन किया जाना चाहिए।

यहाँ Clojure में एक छोटी-सर्किटिंग नन्द समारोह को लागू करने के लिए मैक्रो का एक उदाहरण है:

(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 [email protected]))))) ; continue with the other expressions otherwise 

(nand true true) 
=> false 

(nand false (println "Expression with a side effect!")) 
=> true