2013-02-07 14 views
12

कभी कभी जब अन्य लोगों के Clojure कोड को देखते हुए, मैं देख रहा हूँ एक समारोह है, जैसे defn के माध्यम से परिभाषित और उसके बाद वर-उद्धरण सिंटैक्स का उपयोग बुलाया:Clojure कार्यों कॉलिंग का उपयोग कर वर-उद्धरण वाक्य रचना

user> (defn a [] 1) 
#'user/a 
user> (a) ; This is how you normally call a function 
1 
user> (#'a) ; This uses the var-quote syntax and produces the same result 
1 

के जीवन के लिए मैं फ़ंक्शन को कॉल करने के इन दो तरीकों के बीच अंतर नहीं समझ सकता। मुझे evaluation प्रलेखन में कुछ भी नहीं मिल रहा है यह कहने के लिए कि क्या होता है जब कॉल का ऑपरेटर एक var होता है जो सुझाव दे सकता है कि दूसरा फॉर्म क्यों पसंद किया जाएगा। वे दोनों binding असाइनमेंट और सिंटैक्स-उद्धरण में प्रतिक्रिया देते हैं।

तो, क्या कोई कृपया एक कोड नमूना प्रदान कर सकता है जो ऊपर (a) और (#'a) के बीच अंतर को चित्रित करेगा?

संपादित करें: मुझे पता है कि वर-उद्धरण एक वर है कि एक let शाब्दिक बाध्यकारी द्वारा आच्छादित है करने के लिए इस्तेमाल किया जा सकता है, लेकिन यह कोड है कि मैं पर देख रहा हूँ में मामला हो प्रतीत नहीं होता है।

उत्तर

16

(#'a) हमेशा की तरह, वरa को संदर्भित करता है, जबकि (a) स्थानीय बाइंडिंग द्वारा आच्छादित किया जा सकता है:

user> (defn a [] 1) 
#'user/a 
user> (let [a (fn [] "booh")] [(a) (#'a)]) 
["booh" 1] 

लेकिन सबसे वास्तविक वर-उद्धरण/समारोह कॉल का उपयोग करता है सीधे कॉल नहीं कर रहे हैं वर-उद्धरण अभिव्यक्ति , लेकिन इसके बजाय अपने मूल्य को कैश जब में पारित कर दिया है, ताकि उच्च क्रम निर्माणों वर अपने मूल्य के बजाय एक के वर्तमान मूल्य का संदर्भ लें:

(defn a [] 1) 
(defn my-call [f] (fn [] (+ 1 (f)))) 
(def one (my-call a)) 
(def two (my-call #'a)) 
(defn a [] 2) 

user> (one) 
2 
user> (two) 
3 

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

6

दूसरा रूप आपको क्लोजर में रखे गए गोपनीयता प्रतिबंधों को रोकने की अनुमति देता है।

तो, उदाहरण के लिए, यदि आप निजी कार्यों के साथ लाइब्रेरी विकसित करते हैं, लेकिन उन्हें अलग नामस्थान से परीक्षण करना चाहते हैं, तो आप उन्हें सीधे संदर्भित नहीं कर सकते हैं। लेकिन आप var quote वाक्यविन्यास का उपयोग कर उन्हें प्राप्त कर सकते हैं। यह इसके लिए बहुत उपयोगी है।

गोपनीयता, क्लोजर, संक्षेप में, स्वचालित दस्तावेज़ीकरण का एक रूप है, जैसा कि जावा में दिखाई देने वाली गोपनीयता के विपरीत है। आप इसके चारों ओर मिल सकते हैं।

user> (defn- a [] 1) 
#'user/a 
user> (ns user2) 
nil 
user2> (user/a) 
CompilerException java.lang.IllegalStateException: var: #'user/a is not public, compiling:(NO_SOURCE_PATH:1) 
user2> (#'user/a) 
1 
user2> 
+0

अच्छा बिंदु - अब जब आप इसका उल्लेख करते हैं तो मुझे याद है कि यह स्वयं को अतीत में किया गया है। लेकिन जिस कोड को मैं देख रहा हूं वह एक गैर-निजी एफएन फोन कर रहा है, इसलिए मुझे लगता है कि वर्तमान में बाध्य मूल्य की कैशिंग से बचने की संभावना अधिक संभावना है। – Alex

+0

क्योंकि कोड एक निजी रेपो में है। मैंने एक सामान्य प्रश्न पोस्ट किया, दो अच्छे जवाब मिले, और केवल एक ही स्वीकार कर सकते हैं, इसलिए मैंने उस व्यक्ति को स्वीकार किया जिसे मैंने सामान्य मामले का बेहतर जवाब दिया। – Alex

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