यदि आप डिफरेंशियल चर को फिर से परिभाषित करने के लिए उपयोग कर सकते हैं तो यह कैसे अपरिवर्तनीय माना जाता है?


10

क्लोजर सीखने की कोशिश करना और आप मदद नहीं कर सकते हैं, लेकिन लगातार बताया जा सकता है कि क्लोजर कैसे अपरिवर्तनीय डेटा के बारे में है। लेकिन आप आसानी से defसही का उपयोग करके एक चर को फिर से परिभाषित कर सकते हैं ? मुझे लगता है कि क्लोजर डेवलपर्स इससे बचते हैं लेकिन आप किसी भी भाषा में वैरिएबल बदलने से बच सकते हैं। क्या कोई मुझे समझा सकता है कि यह कैसे अलग है, क्योंकि मुझे लगता है कि मैं उस ट्यूटोरियल और किताबों को याद कर रहा हूं जो मैं पढ़ रहा हूं।

एक उदाहरण देने के लिए कि कैसे है

a = 1
a = 2

रूबी में (या ब्लब, यदि आप चाहें तो) अलग से

(def a 1)
(def a 2)

क्लोजर में?

जवाबों:


9

जैसा कि आपने पहले ही देखा था कि क्लोजर में उत्परिवर्तन को हतोत्साहित करने का यह मतलब नहीं है कि यह निषिद्ध है और इसका समर्थन करने वाले कोई निर्माण नहीं हैं। तो आप सही हैं कि 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क्लोजर में निर्माण वैश्विक पर्यावरण को एक्सेस और म्यूट करने के लिए है। व्यवहार में, यह जावा, सी ++, पायथन जैसी अनिवार्य भाषाओं में क्या काम कर सकता है, इसके समान है।

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


1
उत्परिवर्तन से बचना अब तक पसंदीदा प्रोग्रामिंग शैली है। मेरा सुझाव है कि यह कथन इन दिनों हर भाषा पर लागू होता है; सिर्फ क्लोजर नहीं;)
डेविड अरनो

2

Clojure सभी अपरिवर्तनीय डेटा के बारे में है

क्लोजर म्यूटेशन पॉइंट्स (यानी, s, s, s और s) को नियंत्रित करके उत्परिवर्तित अवस्था को प्रबंधित करने के बारे में है । हालाँकि, निश्चित रूप से, कोई भी जावा कोड जो आप इंटरोप के माध्यम से उपयोग करते हैं, जैसा कि वह कर सकता है।RefAtomAgentVar

लेकिन आप आसानी से डिफ राइट का उपयोग करके एक चर को फिर से परिभाषित कर सकते हैं?

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

लिस्प्स के साथ, REPL के माध्यम से इंटरैक्टिव, खोजपूर्ण प्रोग्रामिंग गतिविधियों का प्रदर्शन करने का एक लंबा इतिहास है। इसमें अक्सर नए चर और कार्यों को परिभाषित करना शामिल है, साथ ही पुराने को फिर से परिभाषित करना भी शामिल है। हालांकि, आरईपीएल के बाहर, फिर से defआईएनजी Varको खराब रूप माना जाता है।


1

बहादुर और सच के लिए क्लोजर से

उदाहरण के लिए, रूबी में आप अपने मूल्य के निर्माण के लिए एक चर में कई कार्य कर सकते हैं:

severity = :mild
  error_message = "OH GOD! IT'S A DISASTER! WE'RE "
  if severity == :mild
    error_message = error_message + "MILDLY INCONVENIENCED!"
  else
    error_message = error_message + "DOOOOOOOMED!"
  end

आप क्लोजर में कुछ ऐसा ही करने के लिए ललचा सकते हैं:

(def severity :mild)
  (def error-message "OH GOD! IT'S A DISASTER! WE'RE ")
  (if (= severity :mild)
      (def error-message (str error-message "MILDLY INCONVENIENCED!"))
  (def error-message (str error-message "DOOOOOOOMED!")))

हालाँकि, इस तरह से एक नाम के साथ जुड़े मूल्य को बदलना आपके कार्यक्रम के व्यवहार को समझना कठिन बना सकता है क्योंकि यह जानना अधिक कठिन है कि कौन सा मूल्य किसी नाम के साथ जुड़ा हुआ है या वह मान क्यों बदल गया है। क्लोजर में परिवर्तन से निपटने के लिए उपकरणों का एक सेट है, जिसके बारे में आप अध्याय 10 में जानेंगे। जैसा कि आप क्लीजुर को सीखते हैं, आप पाएंगे कि आपको नाम / मूल्य एसोसिएशन को बदलने की शायद ही आवश्यकता होगी। यहां एक तरीका है जिससे आप पूर्ववर्ती कोड लिख सकते हैं:

(defn error-message [severity]
   (str "OH GOD! IT'S A DISASTER! WE'RE "
   (if (= severity :mild)
     "MILDLY INCONVENIENCED!"
     "DOOOOOOOMED!")))

(error-message :mild)
  ; => "OH GOD! IT'S A DISASTER! WE'RE MILDLY INCONVENIENCED!"

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

हाँ मैं जानता हूँ। लेकिन प्रस्तावित समस्या को हल करने की अनिवार्यता के तरीके को प्रोत्साहित करने के बजाय (जैसे कि बाइंडिंग को बदलना), क्लूजुर ने कवक प्रतिमान को अपनाया।
टियागो डल'का
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.