दिलचस्प पोस्ट
जाओ और सेट स्क्रीन संकल्प Javax.swing टाइमर ठीक दोहराता है, लेकिन ActionListener कुछ भी नहीं करता है NTLM प्रॉक्सी के पीछे एनपीएम सीएसएस का उपयोग कर पृष्ठभूमि छवि को केंद्रित करना एक div में हर 3 divs लपेटें MySQL: ग्रुप बाय में नहीं है NumPy: हटाए गए एनएएन के साथ औसत गणना कैसे आईएसओ 8601 प्रारूप में जावास्क्रिप्ट में समयक्षेत्र ऑफसेट के साथ दिनांक? ऑब्जेक्ट एक न सहेजा क्षणिक उदाहरण का संदर्भ देता है – फ्लशिंग से पहले क्षणिक उदाहरण बचाएं जावा एसोसिएटिव- सरणी .NET HashTable वीएस डिक्शनरी – क्या डिक्शनरी को तेज़ हो सकता है? स्विफ्ट में नेमस्पेस का उपयोग कैसे करें? 'केवल एक रिएक्ट ओनर के पास रिफ हो सकता है।' क्या मतलब है? एसटीएल में सदिश बनाम सूची सामग्री को फिट करने के लिए मैं एक UIScrollView को कैसे आकार देता हूं

सेटक और डिस्वर्र इन लिस्प में

मैं देखता हूं कि प्रैक्टिकल कॉमन लिस्प का इस्तेमाल वैश्विक वैरिएबल को सेट करने के लिए करता है (defvar *db* nil) । क्या यह ठीक उसी उद्देश्य के लिए setq का उपयोग नहीं है?

defvar बनाम setq का उपयोग करने के क्या फायदे / नुकसान हैं?

वेब के समाधान से एकत्रित समाधान "सेटक और डिस्वर्र इन लिस्प में"

चर को पेश करने के कई तरीके हैं

DEFVAR और DEFPARAMETER वैश्विक गतिशील चर परिचय DEFVAR वैकल्पिक रूप से इसे कुछ मान में सेट करता है, जब तक कि वह पहले ही परिभाषित न हो। DEFPARAMETER यह हमेशा प्रदान किए गए मूल्य पर सेट करता है SETQ एक चर को लागू नहीं करता है

 (defparameter *number-of-processes* 10) (defvar *world* (make-world)) ; the world is made only once. 

ध्यान दें कि आप शायद x , y , stream , limit , जैसे नामों के साथ चर को DEFVAR नहीं चाहते … क्यों? क्योंकि इन चर को विशेष रूप से घोषित किया जाएगा और इसे वापस करना मुश्किल होगा। विशेष घोषणा वैश्विक है और वैरिएबल के सभी आगे उपयोग गतिशील बाइंडिंग का उपयोग करेगा।

खराब:

 (defvar x 10) ; global special variable X, naming convention violated (defvar y 20) ; global special variable Y, naming convention violated (defun foo () (+ xy)) ; refers to special variables X and y (defun bar (xy) ; OOPS!! X and Y are special variables ; even though they are parameters of a function! (+ (foo) xy)) (bar 5 7) ; -> 24 

बेहतर: हमेशा अपने नामों के साथ विशेष चर को चिह्नित करें!

 (defvar *x* 10) ; global special variable *X* (defvar *y* 20) ; global special variable *Y* (defun foo () (+ *x* *y*)) ; refers to special variables X and y (defun bar (xy) ; Yep! X and Y are lexical variables (+ (foo) xy)) (bar 5 7) ; -> 42 

लोकल व्हेरिएबल्स डीफन , लम्बाडा , एलईटी , मल्टीपल- वर्ड-बीआईएनडी और कई अन्य लोगों के साथ शुरू की गई हैं।

 (defun foo (i-am-a-local-variable) (print i-am-a-local-variable)) (let ((i-am-also-a-local-variable 'hehe)) (print i-am-also-a-local-variable)) 

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

इसके बाद, नए मानों के लिए एक चर सेट करने के लिए कई रूप भी मौजूद हैं। SET , SETQ , SETF और अन्य SETQ और SETF दोनों लेक्सिकल और विशेष (गतिशील) वेरिएबल्स सेट कर सकते हैं।

यह पोर्टेबल कोड के लिए आवश्यक है जो कि पहले से घोषित वेरिएबल सेट करता है घोषित वैरिएबल सेट करने का सटीक प्रभाव मानक द्वारा अनिर्धारित है।

इसलिए, यदि आप जानते हैं कि आपके सामान्य लिस्प कार्यान्वयन क्या करता है, तो आप इसका उपयोग कर सकते हैं

 (setq world (make-new-world)) 

टॉप-ईवाल-प्रिंट-लूप में ऊपरी भाग में लेकिन इसे अपने कोड में उपयोग न करें, क्योंकि प्रभाव पोर्टेबल नहीं है आमतौर पर SETQ चर सेट करेगा लेकिन कुछ कार्यान्वयन भी वैरिएबल स्पेशल घोषित कर सकता है जब उसे पता नहीं होता है (सीएमयू कॉमन लिस्प डिफ़ॉल्ट रूप से करता है)। यह लगभग हमेशा ऐसा नहीं होता है जो चाहें यदि आप जानते हैं कि आप क्या करते हैं, लेकिन कोड के लिए नहीं, तो इसका उपयोग आकस्मिक उपयोग के लिए करें।

मुझे भी:

 (defun make-shiny-new-world () (setq world (make-world 'shiny))) 

सबसे पहले, ऐसे चर को *world* (आसपास के अक्षर के साथ) के रूप में लिखा जाना चाहिए, यह स्पष्ट करने के लिए कि यह एक वैश्विक विशेष चर है दूसरा, इसे पहले DEFVAR या DEFPARAMETER साथ घोषित किया जाना चाहिए था।

एक विशिष्ट लिस्प कंपाइलर शिकायत करेगा कि ऊपर के चर को अघोषित किया गया है। चूंकि वैश्विक लैक्सिकल वैरिएबल सामान्य लिस्प में मौजूद नहीं हैं, इसलिए संकलक को डायनेमिक लुकअप के लिए कोड उत्पन्न करना है। कुछ कंपाइलर तो कहते हैं, ठीक है, हम मानते हैं कि यह एक गतिशील लुकअप है, चलो इसे विशेष होने के लिए घोषित करते हैं – चूंकि हम वैसे भी मानते हैं।

defvar एक गतिशील चर का परिचय देता है, जबकि setq एक गतिशील या लेक्सिकल चर के लिए एक मान निर्दिष्ट करने के लिए प्रयोग किया जाता है। एक डायनामिक वैरिएबल के मूल्य को पर्यावरण में देखा जाता है, जो फ़ंक्शन कॉल करता है, जबकि एक लेक्सिकल वेरिएबल के मान को पर्यावरण में देखा जाता है जहां फ़ंक्शन परिभाषित किया गया था। निम्न उदाहरण अंतर को स्पष्ट कर देगा:

 ;; dynamic variable sample > (defvar *x* 100) *X* > (defun fx () *x*) FX > (fx) 100 > (let ((*x* 500)) (fx)) ;; gets the value of *x* from the dynamic scope. 500 > (fx) ;; *x* now refers to the global binding. 100 ;; example of using a lexical variable > (let ((y 200)) (let ((fy (lambda () (format t "~a~%" y)))) (funcall fy) ;; => 200 (let ((y 500)) (funcall fy) ;; => 200, the value of lexically bound y (setq y 500) ;; => y in the current environment is modified (funcall fy)) ;; => 200, the value of lexically bound y, which was ;; unaffected by setq (setq y 500) => ;; value of the original y is modified. (funcall fy))) ;; => 500, the new value of y in fy's defining environment. 

डायनेमिक वैरिएबल एक डिफ़ॉल्ट मान के पास जाने के लिए उपयोगी हैं। उदाहरण के लिए, हम डायनामिक वैरिएबल *out* को मानक आउटपुट में बाँध सकते हैं, ताकि यह सभी io फ़ंक्शंस का डिफ़ॉल्ट आउटपुट हो। इस व्यवहार को ओवरराइड करने के लिए, हम सिर्फ एक स्थानीय बंधन लागू करते हैं:

 > (defun my-print (s) (format *out* "~a~%" s)) MY-PRINT > (my-print "hello") hello > (let ((*out* some-stream)) (my-print " cruel ")) ;; goes to some-stream > (my-print " world.") world 

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

defvar एक वैरिएबल के लिए एक मान निर्दिष्ट करेगा, अगर यह पहले से ही निर्दिष्ट नहीं है। इसलिए *x* की निम्नलिखित री-परिभाषा मूल बाध्यकारी नहीं बदलेगी:

 > (defvar *x* 400) *X* > *x* 100 

हम setq का उपयोग करके *x* लिए एक नया मान असाइन कर सकते हैं:

 > (setq *x* 400) 400 > *x* 400 > (fx) 400 > (let ((*x* 500)) (fx)) ;; setq changed the binding of *x*, but ;; its dynamic property still remains. 500 > (fx) 400 

DEFVAR एक नया चर स्थापित करता है SETQ एक चर को असाइन करता है

अधिकांश लिस्प कार्यान्वयन मैं उपयोग किया है एक चेतावनी जारी अगर आप एक चर में SETQ जो अभी तक मौजूद नहीं है

defvar और defparameter दोनों वैश्विक चर परिचय केन नोट्स के रूप में, setq एक चर के लिए असाइन करता है

इसके अलावा, defvar पहले से defvar -ed कुछ clobber नहीं होगा Seibel बाद में किताब (अध्याय 6) में कहते हैं: "व्यावहारिक रूप से बोलते हुए, आप वे चर को परिभाषित करने के लिए DEFVAR का उपयोग करना चाहिए जिसमें वे डेटा शामिल होंगे जो आप चाहते हैं, भले ही आपने स्रोत कोड में परिवर्तन किया हो जो चर का उपयोग करता है।"

http://www.gigamonkeys.com/book/variables.html

उदाहरण के लिए, यदि आपके पास साधारण डाटाबेस अध्याय में डेटाबेस के लिए वैश्विक *db* :

 (defvar *db* nil) 

… और आप इसके साथ आरईपीएल में खेलना शुरू करते हैं – चीजों को हटाने, आदि – लेकिन फिर आप स्रोत फ़ाइल में बदलाव करते हैं जिसमें उस डिफॉर्म फॉर्म को शामिल किया जाता है, उस फाइल को पुनः लोड करने से *db* और सभी परिवर्तनों को पोंछ नहीं होगा हो सकता है कि आपने … मुझे विश्वास है कि defparameter विल defparameter होगा। एक अधिक अनुभवी लिस्पर कृपया मुझे सही करें अगर मैं गलत हूं, हालांकि।