2012-10-17 5 views
8

मैं संदर्भ पर एक नज़र था: http://clojuredocs.org/clojure_core/clojure.core/bindingक्लोजर के डायनामिक वर्र्स और बाइंडिंग का व्यावहारिक उद्देश्य क्या है?

के साथ-साथ clojure and ^:dynamic और Clojure Dynamic Binding

मैं अभी भी समझ में नहीं आता क्यों binding के लिए की जरूरत है http://clojure.org/vars#Vars%20and%20the%20Global%20Environment, बिल्कुल हर कार्यक्रम के रूप में मैं कर दिया गया है लिखा है उनके बिना और मैं परंपरागत तरीके से उदाहरण लिखने के तरीके ढूंढ सकता हूं - जो मुझे अधिक समझ में आता है। क्या परियोजनाओं/प्रोग्रामिंग प्रतिमानों के उदाहरण हैं जो इसका उपयोग करते हैं?

(def dog {:name "Dog" :sound "Woof"}) 
(def cat {:name "Cat" :sound "Meow"}) 

(defn speak [animal] 
    (str (:name animal) " says " (:sound animal)) 

(println (speak dog)) 
(println (speak cat)) 

कोई मैक्रो, कोई गतिशील बंधन ... अभी भी बहुत साफ:

उदाहरण के लिए

... पशु में उदाहरण के बात करते हैं, आप के साथ एक समान प्रभाव प्राप्त कर सकते हैं।

+0

स्टुअर्ट सिएरा इस ब्लॉग पोस्ट में क्लोजर में गतिशील स्कॉइंग के प्रभावों के बारे में बात करते हैं: http://stuartsierra.com/2013/03/29/perils-of- गतिशील-स्कोप –

उत्तर

11

वहाँ सख्ती से उनके लिए एक की जरूरत नहीं है: के रूप में आप ठीक ही निरीक्षण क्या आप binding बिना चाहते कुछ भी कर सकते है, और वास्तव अगर binding मौजूद नहीं था तो आप सकता है यह अपेक्षाकृत आसानी से जावा के फिर से लागू मैक्रो और का उपयोग कर ThreadLocal एस।

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

यह विशेष रूप से उपयोगी होता है जब आप गहरे घोंसले वाले उच्च ऑर्डर फ़ंक्शंस लिख रहे हैं और कॉल स्टैक में प्रत्येक फ़ंक्शन में अतिरिक्त पैरामीटर जोड़ना नहीं चाहते हैं ताकि गहरे अंदर एम्बेडेड निचले स्तर के फ़ंक्शंस में कुछ मूल्य पारित किया जा सके।

अपने उदाहरण पर निर्माण करने के लिए:

(def ^:dynamic *loud-noises* false) 

(defn speak [animal] 
    (str (:name animal) " says " 
      (let [sound (:sound animal)] 
      (if *loud-noises* (.toUpperCase sound) sound)))) 

(speak dog) 
=> "Dog says Woof" 

(binding [*loud-noises* true] 
    (speak dog)) 
=> "Dog says WOOF" 

नोट मैं speak समारोह के लिए एक अतिरिक्त पैरामीटर जोड़ने का अलग व्यवहार प्राप्त करने की आवश्यकता नहीं किया था। एक अतिरिक्त पैरामीटर जोड़ना इस मामले में मामूली होगा, लेकिन कल्पना करें कि speak फ़ंक्शन को जटिल उच्च ऑर्डर फ़ंक्शन के भीतर गहरा दफनाया गया था .....

फिर भी, मुझे लगता है कि समग्र रूप से सबसे अच्छी सलाह गतिशील बाध्यकारी से बचने के लिए है वास्तव में इसकी जरूरत है। यदि आप कर सकते हैं तो स्पष्ट पैरामीटर जोड़ना आम तौर पर बेहतर होता है: प्रत्यक्ष पैरामीटर परीक्षणों और कार्यों के बारे में तर्क करना आसान बनाता है।

+1

आप अतिरिक्त पैरामीटर जोड़ने के लिए बाध्यकारी क्यों पसंद करेंगे एक गहरा घोंसला समारोह में हर समारोह के लिए? अगर मेरा फ़ंक्शन '(कुत्ता बोलें)' और '(क्लोज-दरवाजा)' कहता है, तो मुझे कैसे पता चलेगा कि '* जोर-शोर * '' बोलने के अनुरूप है और' क्लोज-दरवाजा 'नहीं है? – ToBeReplaced

+2

@ToBeReplaced मुझे लगता है कि आप गतिशील बाध्यकारी के साथ बिल्कुल खतरे को हाइलाइट करते हैं और इसका उपयोग करने वाले डिज़ाइनों को बहुत सावधानी से माना जाना चाहिए।गतिशील बाध्यकारी संदर्भों को उन परतों में स्थानांतरित करने की अनुमति देता है जहां आप मध्य को नियंत्रित नहीं करते हैं। उदाहरण के लिए क्लोजर प्रिंट फ़ंक्शंस किसी तृतीय पक्ष फ़ंक्शन के अंदर उपयोग किए जाने पर भी आउटपुट स्ट्रीम को रीबाउंड करने की अनुमति देता है (जिसमें आउटपुट स्ट्रीम पैरामीटर नहीं होता है)। यह थ्रेड विशिष्ट व्यवहार को सेट करने की भी अनुमति देता है लेकिन मुझे संदेह है कि अधिकांश एपीआई में गतिशील बाध्यकारी अधिक फायदेमंद है। –

+0

नीचे मेरी पोस्ट देखें। – zcaudate

1

बस ऊपर मिकरा के उदाहरण पर चल रहा है .. मैं देख सकता हूं कि आप इसे कम अभिव्यक्तिपूर्ण भाषा में क्यों करेंगे लेकिन क्लोजर इतना अभिव्यक्तिपूर्ण है, इसलिए मैं इसे फिर से लिखूंगा ... loud-noise फ़ंक्शन को थोड़ा बदल दिया जा सकता है बात करने के लिए अतिरिक्त पैरामीटर जोड़कर एक ही प्रभाव को प्राप्त करने ...

(defn speak [animal & opts] 
    (let [sound (:sound animal) 
     sound (if (some #(= % :louder) opts) 
       (.toUpperCase sound) sound)] 
    (str (:name animal) " says " sound))) 


> (speak dog) 
;;=> "Dog says Woof" 
> (speak dog :louder) 
;;=> "Dog says WOOF" 

एक त्वरित और गंदे समाधान ऊपर हैक करने यदि आप मूल कोड को बदल नहीं सकते सिर्फ एक तरह से बाध्यकारी है?

+4

आपके पास हमेशा अतिरिक्त पैरामीटर जोड़ने की क्षमता नहीं है - उदाहरण के लिए यदि आप लाइब्रेरी कोड में फ़ंक्शन पास कर रहे हैं तो क्या होगा? या यदि कार्य सामान्य उद्देश्य एचओएफ हैं जो आप पैरामीटर के साथ प्रदूषित नहीं करना चाहते हैं जो केवल एक विशेष मामले में उपयोग किया जाता है? – mikera

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