2011-10-16 22 views
9

संपादित करें: मैंने पहले जवाब के बाद उदाहरण कोड बदल दिया क्योंकि मैं एक साधारण संस्करण के साथ आया जो एक ही प्रश्न पूछता है।कॉमन लिस्प स्कोपिंग (गतिशील बनाम लेक्सिकल)

मैं वर्तमान में आम लिस्प के स्कोपिंग गुणों को सीख रहा हूं। मैंने सोचा कि मुझे ठोस समझ है, मैंने कुछ उदाहरणों को कोड करने का फैसला किया है कि मैं परिणाम की भविष्यवाणी कर सकता हूं, लेकिन स्पष्ट रूप से मैं गलत था।

उदाहरण 1:: मैं तीन सवाल है, नीचे एक उदाहरण से संबंधित हर एक है

(defmethod fun1 (x) 
    (print x) 
    (fun2)) 

(defmethod fun2() 
    (print x)) 

(fun1 5) 

आउटपुट:

5 
*** - EVAL: variable X has no value 

प्रश्न: यह समझ में आता है। एक्स स्थिर रूप से स्कॉप्ड है और fun2 के पास एक्स के मान को स्पष्ट रूप से पारित किए बिना कोई रास्ता नहीं है।

उदाहरण 2:

(defvar x 100) 

(defmethod fun1 (x) 
    (print x) 
    (fun2)) 

(defmethod fun2() 
    (print x)) 

(fun1 5) 

आउटपुट:

5 
5 

प्रश्न: मुझे समझ नहीं आता क्यों एक्स के बजाय एक मूल्य के होने का, मूल्य कि fun1 दे दिया साथ fun2 को अचानक दिखाई दे रहा है 100 में से ...

उदाहरण 3:

(setf x 100) 

(defmethod fun1 (x) 
    (print x) 
    (fun2)) 

(defmethod fun2() 
    (print x)) 

(fun1 5) 

आउटपुट:

5 
100 

प्रश्न: मैं एक अघोषित चर पर setf बुला जाहिरा तौर पर अपरिभाषित है के बाद से इन परिणामों को अनदेखा कर देना चाहिए? यह वही है मैं अपने दूसरे उदाहरण में उम्मीद करेंगे ...

किसी भी अंतर्दृष्टि बहुत सराहना की जाएगी ...

+0

यहाँ एक छोटा सा चारों ओर खेलने के बाद मेरी भोली विवरण है ... मुझे पता है कि अगर मैं करीब हूँ चलो .. उदाहरण के 1: कोई स्पष्टीकरण नहीं उदाहरण 2 की जरूरत है: एक गतिशील चर के रूप में घोषित करने एक्स के सभी उदाहरणों का कारण बनता है एक्स को डायनामिक वैरिएबल स्टैक पर रन टाइम पर देखा जाना चाहिए, जो गतिशील चर होने के बावजूद fun2 से x के मान को प्राप्त करने के लिए fun2 का कारण बन जाएगा। उदाहरण 3: कोई विचार नहीं ... मुझे लगता है कि यह अपरिभाषित –

+0

* बढ़ रहा है * प्रश्न अच्छा है। * भिक्षा * प्रश्न ** खराब है ** ** –

+0

DEFMETHOD के बजाय DEFUN का उपयोग करें। इन उदाहरणों में एक डेफमेथोड की आवश्यकता नहीं है। डेफन एक साधारण काम बनाता है। डेफमेथोड सामान्य कार्यों के लिए है, जहां आपको कुछ प्रेषण की आवश्यकता है। –

उत्तर

18

एक अपरिभाषित चर SETF का उपयोग कर स्थापित करने का प्रभाव एएनएसआई कॉमन लिस्प में अपरिभाषित है होता है।

DEFVAR एक विशेष चर परिभाषित करेगा। यह घोषणा वैश्विक है और एलईटी बाइंडिंग पर भी इसका असर पड़ता है। यही कारण है कि सम्मेलन द्वारा इन चरों को *foo* के रूप में लिखा गया है। यदि आपने कभी डीएफवीएआर के साथ एक्स को परिभाषित किया है, तो इसे विशेष घोषित किया गया है और इसे बाद में व्याख्यात्मक घोषित करने का कोई तरीका नहीं है।

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

अद्यतन

  • उदाहरण 1।

कुछ भी देखने के लिए नहीं।

  • उदाहरण 2

X विशेष घोषित किया गया है। परिवर्तनीय एक्स के सभी उपयोग अब गतिशील बाध्यकारी का उपयोग करें। फ़ंक्शन को कॉल करते समय, आप X से 5 को गतिशील रूप से बांधते हैं। अन्य कार्य अब इस गतिशील बाध्यकारी तक पहुंच सकते हैं और वह मान प्राप्त कर सकते हैं।

  • उदाहरण 3

यह कॉमन लिस्प में अपरिभाषित व्यवहार है। आप एक अविकसित चर सेट कर रहे हैं। तब क्या होता है कार्यान्वयन निर्भर है। आपका कार्यान्वयन (अधिकतर कुछ ऐसा ही करता है) एक्स से 100 का प्रतीक मान सेट करता है। FUN1 में, एक्स को लंबवत रूप से बाध्य किया जाता है। XUN का मूल्यांकन करने वाले एक्स में एक्स

किसी कार्यान्वयन के उदाहरण के रूप में कुछ और किया गया है: सीएमयूसीएल कार्यान्वयन ने एक्स को घोषित किया होगा 3 डिफ़ॉल्ट होने के लिए डिफ़ॉल्ट रूप से। एक अपरिभाषित चर सेट करना भी इसे विशेष घोषित करता है।

नोट

पोर्टेबल मानक अनुरूप कॉमन लिस्प कोड में वैश्विक चर DEFVAR और DEFPARAMETER साथ परिभाषित कर रहे हैं। दोनों इन चरों को विशेष होने की घोषणा करते हैं। इन चर के सभी उपयोगों में अब गतिशील बाध्यकारी शामिल है।

याद रखें:

((lambda (x) 
    (sin x)) 
10) 

मूल रूप से के रूप में

(let ((x 10)) 
    (sin x)) 

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

यह सामान्य लिस्प मानक में निर्दिष्ट है। उदाहरण के लिए SPECIAL declaration पर स्पष्टीकरण देखें।

+0

मैंने अपनी मूल पोस्ट को अधिक सटीक उदाहरणों और प्रश्नों के साथ अपडेट किया है जो दर्शाते हैं कि मुझे समझ में क्या परेशानी हो रही थी। विशेष रूप से, मेरे पहले उदाहरण –

+0

की तुलना में मेरे दूसरे उदाहरण में दिखाया गया व्यवहार स्पष्टीकरण के लिए धन्यवाद! मुझे नहीं लगता कि मैं सामान्य मुक्त चर के समान कार्यों के पैरामीटर मानों को प्रभावित करने की अपेक्षा कर रहा था ... लेकिन मुझे लगता है कि हर उल्लेख का इलाज समान होता है। –

+1

@ antman8969: परिवर्तनीय उपयोग हर जगह समान है। थोड़ा आश्चर्यजनक बात यह है कि फ़ंक्शन पैरामीटर को गतिशील रूप से बाध्य किया जा सकता है और वे DEFVAR के साथ चर की परिभाषा से प्रभावित होते हैं। –