जैसा कि आपने पहले ही देखा था कि क्लोजर में उत्परिवर्तन को हतोत्साहित करने का यह मतलब नहीं है कि यह निषिद्ध है और इसका समर्थन करने वाले कोई निर्माण नहीं हैं। तो आप सही हैं कि def
आप का उपयोग पर्यावरण में एक बंधन को बदल सकता है / कर सकता है, जो अन्य भाषाओं में असाइनमेंट के समान है (देखें varj पर Clojure प्रलेखन )। वैश्विक परिवेश में बाइंडिंग बदलने से आप डेटा ऑब्जेक्ट भी बदलते हैं जो इन बाइंडिंग का उपयोग करते हैं। उदाहरण के लिए:
user=> (def x 1)
#'user/x
user=> (defn f [y] (+ x y))
#'user/f
user=> (f 1)
2
user=> (def x 100)
#'user/x
user=> (f 1)
101
ध्यान दें कि बाइंडिंग को फिर से परिभाषित करने के बाद x
, फ़ंक्शन f
भी बदल गया है, क्योंकि इसका शरीर उस बंधन का उपयोग करता है।
इसकी तुलना उन भाषाओं से करें जिनमें किसी चर को पुनर्परिभाषित करने से पुरानी बाइंडिंग डिलीट नहीं होती है, लेकिन यह केवल छाया देता है, अर्थात यह नई परिभाषा के बाद आने वाले दायरे में इसे अदृश्य बना देता है। देखें कि यदि आप SML REPL में समान कोड लिखते हैं तो क्या होता है:
- val x = 1;
val x = 1 : int
- fun f y = x + y;
val f = fn : int -> int
- f 1;
val it = 2 : int
- val x = 100;
val x = 100 : int
- f 1;
val it = 2 : int
ध्यान दें कि दूसरी परिभाषा के बाद x
, फ़ंक्शन f
अभी भी उस बाइंडिंग का उपयोग करता है जो x = 1
उस दायरे में थी जब इसे परिभाषित किया गया था, अर्थात बाइंडिंग val x = 100
पिछले बाइंडिंग को अधिलेखित नहीं करती है val x = 1
।
बॉटमलाइन: क्लॉजुरे वैश्विक वातावरण और उसमें होने वाली बाइंडिंग को फिर से परिभाषित करने की अनुमति देता है। इससे बचना संभव होगा, क्योंकि अन्य भाषाएं जैसे एसएमएल करती हैं, लेकिन def
क्लोजर में निर्माण वैश्विक पर्यावरण को एक्सेस और म्यूट करने के लिए है। व्यवहार में, यह जावा, सी ++, पायथन जैसी अनिवार्य भाषाओं में क्या काम कर सकता है, इसके समान है।
फिर भी, क्लोजर बहुत सारे निर्माण और पुस्तकालय प्रदान करता है जो उत्परिवर्तन से बचते हैं, और आप इसका उपयोग किए बिना एक लंबा रास्ता तय कर सकते हैं। उत्परिवर्तन से बचना अब तक क्लोजर में पसंदीदा प्रोग्रामिंग शैली है।