2012-07-23 13 views
6

क्यों Clojure कोड के इस बिट:Clojure लगातार और नक्शा समारोह

user=> (map (constantly (println "Loop it.")) (range 0 3)) 

यील्ड इस उत्पादन:

Loop it. 
(nil nil nil) 

मैं इसे एक पक्ष के रूप में मुद्रित करने के लिए "लूप यह" तीन बार उम्मीद थी समारोह को तीन बार मूल्यांकन करने का प्रभाव।

उत्तर

9

constantly कई बार अपने तर्क का मूल्यांकन नहीं करता है। यह एक समारोह है, मैक्रो नहीं, इसलिए constantly रनों से पहले एक बार तर्क का मूल्यांकन किया जाता है। सभी constantly क्या यह अपना (मूल्यांकन) तर्क लेता है और एक ऐसा फ़ंक्शन देता है जो हर बार दिए जाने वाले दिए गए मान को लौटाता है (जैसा कि मैंने कहा था, कुछ भी फिर से मूल्यांकन किए बिना, तर्क का मूल्यांकन constantly से पहले भी किया जाता है)।

यदि आप सभी करना चाहते हैं तो श्रेणी में प्रत्येक तत्व के लिए (println "Loop it") पर कॉल करना है, तो आपको constantly के बजाय फ़ंक्शन को मानचित्र में भेजना चाहिए। ध्यान दें कि आपको वास्तव में इसे एक फ़ंक्शन के रूप में पास करना होगा, न कि मूल्यांकन की अभिव्यक्ति।

+0

स्रोत पर देखा गया। यह एक विजेता की तरह दिखता है। – Mike

+0

एक ऐसे तर्क में स्पष्ट रूप से गुज़रने से बचने के लिए लगातार उपयोग करने का प्रयास कर रहा था जिसकी मुझे आवश्यकता नहीं है। हालांकि, इसके लिए बस जाएगा। – Mike

+10

ध्यान दें कि यदि आप केवल दुष्प्रभाव चाहते हैं, तो आपको 'doseq' या 'dotimes' का उपयोग करना चाहिए। चूंकि 'नक्शा' आलसी है, इसलिए आपको वह परिणाम नहीं मिलेगा जब तक आप इसे 'डोल' या 'डोरुन' के साथ मजबूर नहीं करते। –

3

आप usig repeatedly और लैम्ब्डा अभिव्यक्ति द्वारा अपने इरादे के करीब एक व्यवहार प्राप्त कर सकते हैं।

उदाहरण के लिए:

(repeatedly 3 #(println "Loop it")) 

जब तक आप आरईपीएल पर हैं, यह एक dorun या इसी तरह से घिरे होने की जरूरत है। repeatedly आलसी है।

+0

लैम्ब्डा संकलित नहीं करेगा क्योंकि मैं उस तर्क का उपयोग करना चाहता हूं जो मैं पास करता हूं। इस मामले में, मैं सिर्फ तर्क को अनदेखा करना चाहता हूं। – Mike

+0

मैंने आपके उपयोग के समान, उपयोग का एक उदाहरण जोड़ा है। – sortega

+0

ओह, यह और अधिक समझ में आता है। धन्यवाद! – Mike

3

जैसा कि sepp2k सही ढंग से इंगित करता है constantly एक कार्य है, इसलिए इसका तर्क केवल एक बार मूल्यांकन किया जाएगा।

प्राप्त करने के लिए क्या तुम यहाँ क्या कर रहे हैं का उपयोग करने के होगा मुहावरेदार रास्ता doseq:

(doseq [i (range 0 3)] 
    (println "Loop it.")) 

या वैकल्पिक रूप से dotimes (जो एक छोटे से अधिक संक्षिप्त और इस विशेष मामले में कुशल है के रूप में आप वास्तव में उपयोग नहीं कर रहे अनुक्रम range द्वारा उत्पादित):

(dotimes [i 3] 
    (println "Loop it.")) 
इन समाधानों में से

दोनों गैर आलसी हैं, जो शायद तुम क्या चाहते है अगर तुम सिर्फ साइड इफेक्ट के लिए कुछ कोड चल रहे हैं।

संबंधित मुद्दे