2010-08-22 20 views
12

ठीक है यहाँ मैं क्याclojure टाल समारोह निष्पादन

(defn addresses [person-id] 
;addresses-retrival) 

(defn person [id] 
    (merge {:addresses (addresses id)} {:name "john"})) 

करने के लिए ऊपर व्यक्ति समारोह मैं चाहता हूँ पतों की तरह ही जब मैं करना

(:addresses (person 10)) 

, केवल मांग पर पुनः प्राप्त किया जा करने के लिए कोशिश कर रहा हूँ है और जब

(person 10) 

मुझे यकीन नहीं है कि मैं इस अधिकार के बारे में जा रहा हूं, क्लोजर के लिए नया होना।

उत्तर

10

आप देरी का उपयोग कर सकते हैं।

(defn person [id] 
    (delay {:addresses (addresses id) :name "john"})) 

(व्यक्ति 2) फिर कुछ भी मूल्यांकन किए बिना देरी वापस कर देगा। सामग्री तक पहुंचने और देरी वाली वस्तु का मूल्यांकन करने के लिए, बल या deref (या @) का उपयोग करें।

(:addresses @(person 5)) 

वैकल्पिक रूप से, आप केवल पते पर देरी डाल सकते हैं।

(defn person [id] 
    {:addresses (delay (addresses id)) :name "john"}) 

जो आपकी समस्या के आधार पर अच्छा हो सकता है।

यह परिभाषित करने के लिए अनुमति देता है:

(defn get-address [person] 
    @(:address person)) 

कौन सा देरी का पता मिलता है और यह बाध्य करेगा। (फोर्सिंग का मतलब पहली बार कंप्यूटिंग करना और मजबूर परिणाम किसी अन्य समय को पुनर्प्राप्त करना)।

+0

आपको बहुत बहुत धन्यवाद। मैं सोच रहा था कि इसे पारदर्शी बनाया जा सकता है, इसलिए इसे पहली बार इस्तेमाल किया जा सकता है। मैन्युअल रूप से मूल्यांकन मजबूर करने के बजाय? – Surya

+0

मुझे ऐसा नहीं लगता है। जहां तक ​​मुझे पता है, क्लोजर आलस्य और बल में स्पष्ट है। –

+0

मेरा लैज़िमैप [लाइब्रेरी] (http://bitbucket.org/kotarak/lazymap) ठीक वही करता है। यह सभी मानचित्र प्रकारों के लिए पारदर्शी ड्रॉप-इन्स प्रदान करता है, जो उनके मूल्यों की गणना केवल तभी प्राप्त किए जाते हैं जब उन्हें वास्तव में पुनर्प्राप्त किया जाता है। – kotarak

1

कम से कम जहां तक ​​अनुक्रमों को जाना है, क्लोजर को बिना किसी जानकारी के आलसी आलसी आलसी है।

यहाँ, गिनती के रूप में अपना पता-पुनर्प्राप्ति मॉडलिंग, कोशिश:

(defn addresses [person-id] 
    (iterate #(do (println %) (inc %)) person-id)) 

(defn person [id] 
    (merge {:addresses (addresses id)} {:name "john"})) 

(def people (map person (range 100))) 

अब तक यह कुछ भी मुद्रित है नहीं है, लेकिन अगर आप कहते हैं:

(doall (take 5 (:addresses (nth people 10)))) 

तो फिर तुम देखना चाहिए मुद्रण उन मामलों में होता है जिन्हें दसवीं जगह में पांच गिनने की आवश्यकता होती है। मैं कल्पना करता हूं कि आप जिस प्रकार के व्यवहार चाहते हैं वह हो सकता है?

तो एक आलसी अनुक्रम का निर्माण करने के अपना पता देखने मिलता है (नक्शा, फिल्टर, को कम सब काम हो जाएगा)

0

मैं आप क्या उम्मीद के पास कुछ सुझाव दे सकते हैं।

; Note the use of anonymouns function. #(addresses id) 
(defn person [id] 
    (merge {:addresses #(addresses id)} {:name "john"})) 

; :addresses returns a function. Evaluate it by wrapping it in another set of parans. 
((:addresses (person 10))) 
1

आप addresses समारोह जो जब बाद में बुलाया पते हासिल करेगा से एक समारोह लौट सकते हैं। कुछ इस तरह:

(defn addresses [person-id] 
#(;addresses-retrival)) 

(defn person [id] 
    (merge {:addresses ((addresses id))} {:name "john"})) 

नोट addresses समारोह (# का उपयोग कर बनाया) एक गुमनाम समारोह और person फ़ंक्शन से कोष्ठक की एक अतिरिक्त जोड़ी का उपयोग कर कि अज्ञात फ़ंक्शन कॉल करता है।

0

याद रखें कि देरी याद की जाती है, इसलिए आपके पतों की देरी की लगातार कॉल हमेशा पहली बार उसी पते को प्राप्त करेगी जब आपने देरी को खराब कर दिया था।

(defn addresses [person-id] 
    {:home (str (rand-int 100) " Cool St.") :work "1243 Boring St."}) 

(defn person [id] 
    (merge {:addresses (delay (addresses id))} {:name "john"})) 

(let [person1 (person 1)] 
    (println @(:addresses person1)) 
    (println @(:addresses person1))) 

यह प्रिंट होगा:

{:home 65 Cool St., :work 1243 Boring St.} 
{:home 65 Cool St., :work 1243 Boring St.} 

सूचना कैसे घर का पता देरी के दूसरे deref पर अपरिवर्तित है।

यदि आप इस व्यवहार को नहीं चाहते हैं तो आपको इसके बजाय फ़ंक्शन क्लोजर का उपयोग करने की आवश्यकता है।

(defn addresses [person-id] 
    {:home (str (rand-int 100) " Cool St.") :work "1243 Boring St."}) 

(defn person [id] 
    (merge {:addresses (fn [] (addresses id))} {:name "john"})) 

(let [person1 (person 1)] 
    (println ((:addresses person1))) 
    (println ((:addresses person1)))) 

यह प्रिंट होगा:

{:home 16 Cool St., :work 1243 Boring St.} 
{:home 31 Cool St., :work 1243 Boring St.} 

सूचना कैसे घर का पता बंद करने के लिए उप सिलसिलेवार फोन पर अलग था।

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