2012-03-28 10 views
10

मैं क्लोजर में कुछ व्यवहार को समझने की कोशिश कर रहा हूं।क्लोजर एक ही नाम के साथ कई बाइंडिंग्स को अनुमति देता है

(let [a 1 a 2 a b] a) 
; (= a 2) 

(let [a 1 a 2 a 3] a) 
; (= a 3) 

मैं समझता हूँ कि चलो बाइंडिंग मूल्यांकन किया जाता है, और यह सब ज्यादातर समझ में आता है:

यह एक लेट ही बंधन-नाम के साथ बाध्यकारी बनाने के लिए संभव है कई बार दोहराया।

दस्तावेज़ों से मेरी समझ यह है कि "चलो के साथ बनाए गए स्थानीय चर नहीं हैं। एक बार उनके मूल्य कभी नहीं बदलते!"

क्या उपर्युक्त वाक्यविन्यास वास्तव में बाइंडिंग के मूल्य को बदलता है?

ऐसा लगता है कि इसे एक त्रुटि उठानी चाहिए।

ओर टिप्पणी के एक प्रकार के रूप में:

दिलचस्प बात यह है कि आप कर सकते उत्पादन clojurescript साथ जे एस के रूप में ऊपर:

var a__36584 = 1, b__36585 = 2, a__36586 = b__36585; 
var a__30671 = 1, a__30672 = 2, a__30673 = 3; 

यहाँ हम है कि मूल्यों सब वास्तव में अलग चर, जो की ओर इशारा कर रहे हैं देख सकते हैं कवर के तहत हो रहा है, लेकिन कुछ स्पष्टीकरण बहुत उपयोगी होगा।

उत्तर

22

(let [a 1, a 2] a) कार्यात्मक रूप से (let [a 1] (let [a 2] a)) के बराबर है, जो समझना आसान हो सकता है। बाद के मामले में, यह महसूस करना अपेक्षाकृत आसान है कि आप a के मान को "संशोधित" नहीं कर रहे हैं, लेकिन एक अलग मूल्य के साथ a नामक एक नया, असंबंधित चर प्रस्तुत करना। आप (let [a 1] (let [a 2] (println a)) a) जैसे कुछ के साथ इसका प्रभाव देख सकते हैं - यह 2 प्रिंट करता है, और फिर 1 देता है, क्योंकि बाहरी a कभी नहीं बदला जाता है, केवल अस्थायी रूप से छुपाया जाता है। (let [a 1, a 2] a) बस a नामक एक मान पेश कर रहा है जो तुरंत दायरे से बाहर हो जाता है। बेशक, बाहरी a आंतरिक a के मूल्य तक उपलब्ध है, इसलिए आप (let [a 1, a (inc a)] a) जैसे कुछ कर सकते हैं।

8

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

(let [a some-vector, a (first a), a (:key a)] a) 

और निश्चित रूप से यह कोई त्रुटि नहीं है। जैसा कि आपने देखा है, ये बाइंडिंग आंतरिक रूप से विभिन्न चर को प्रभावित करती हैं। यह अनिवार्य रूप से क्लोजर लेक्सिकल चर के अपरिवर्तनीयता है। इस शब्दावली चर के कारण रिबाइंडिंग में स्वच्छ अर्थशास्त्र (अंतिम बाध्यकारी "जीत") है, और इसे अस्वीकार करने का कोई कारण नहीं है।

6

अन्य उत्तरों ने सही ढंग से ध्यान दिया है कि चलो सिंटैक्स प्रभावी ढंग से पुरानी बाध्यकारी छिपाने के लिए नई बाइंडिंग बनाता है।

(let [d (double d)] 
    ......) 

देना ब्लॉक के भीतर, घ होगा: नोट करने के लिए

एक दिलचस्प अतिरिक्त मुद्दा यह है कि इस Clojure कोड के अनुकूलन के लिए बहुत उपयोगी हो सकता है जब आप जानते हैं कि एक मूल्य के एक विशेष प्रकार का होगा, जैसे है तब एक प्राचीन डबल के रूप में इस्तेमाल किया जाना चाहिए जो कई गणितीय परिचालनों को काफी हद तक तेज कर सकता है।

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

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