2010-07-15 17 views
6

मैं इस तरह एक कोड है। मैं इसे प्रतिलिपि में चला सकता हूं लेकिन कमांड लाइन से नहीं कर सकता। मुझे लगता है कि मुझे आलसी मूल्यांकन समस्या है।आलसी मूल्यांकन समस्या


; items.clj 

(def items (ref [])) 

(defn init-items [] 
    (map 
    #(dosync 
     (alter items conj %)) 
    ["foo" "bar" "baz" ])) 

(init-items) 
(println (first @items)) 

$ java -jar clojure.jar items.clj 
$ nil 

सादर।

उत्तर

4

मिल गया! क्योंकि वहाँ कोई परिणाम वापस

solution

Clojure init-items में map समारोह को चलाने के लिए प्रेरित नहीं है। मैंने निष्पादन को मजबूर करने के लिए doall में लपेट लिया, और प्रतिष्ठा।

+0

मैं काम किया। बहुत बहुत धन्यवाद। – Osman

+3

असल में 'dorun' बेहतर इस मामले के लिए उपयुक्त (' doall' seq यह लपेटता है और यह रिटर्न के सिर पर रखती है, जबकि 'dorun' को छोड़ देता है यह चरण दर चरण और अंत में' रिटर्न nil' है - इस प्रकार यह बेहतर के लिए उपयुक्त है दुष्प्रभाव कोड)। –

+0

@Michal: आप बिल्कुल निश्चित रूप से सही है, कर रहे हैं। मैं Clojure के साथ एक सा dabbled है लेकिन उच्च दक्षता पर पहुंच गया कभी नहीं, और अब, दुर्भाग्य से, यहाँ तक कि जंग शुरू कर रहा है। सुधारों के लिए धन्यवाद! –

4

कुछ विकल्प:

तुम सिर्फ एक संग्रह एक रेफरी में आयोजित किए जाने वाले आइटम का एक समूह को जोड़ने के लिए, आइटम प्रति एक लेन-देन शुरू करने चाहते हैं और conj उन्हें अलग से ing थोड़ा बेकार है। इसके बजाय, आप

(defn init-items [] 
    (dosync (alter items into ["foo" "bar" "baz"]))) 

कर सकता है आप एक आइटम-प्रति-कदम फैशन में यह करने के लिए किसी कारण है, तो मुझे लगता है कि सबसे मुहावरेदार और सुविधाजनक दृष्टिकोण वर्तमान में उपयोग करने के लिए किया जाएगा doseq:

(defn init-items [] 
    (doseq [item ["foo" "bar" "baz"]] 
    (dosync (alter items conj item)))) 

(या आप एक dosync में चादर को स्थानांतरित कर सकता है पूरे doseq और doseq के शरीर में dosync का उपयोग नहीं।)

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