2015-02-02 8 views
5

मैं सिर्फ sharpsign पेट के पाठक मैक्रो पर पढ़ रहा है और यह लग रहा था जैसे कि यह gensym काफ़ी मिलती-जुलती प्रभाव नहीं पड़ामतभेद

Sharpsign बृहदान्त्र:

"एक uninterned प्रतीक का परिचय"

Gensym: "बनाता है और एक ताजा, uninterned प्रतीक रिटर्न"

तो एक साधारण परीक्षण

CL-USER> #:dave 
; Evaluation aborted on #<UNBOUND-VARIABLE DAVE {1002FF77D3}>. 
CL-USER> (defparameter #:dave 1) 
#:DAVE 
CL-USER> #:dave 
; Evaluation aborted on #<UNBOUND-VARIABLE DAVE {100324B493}>. 

कूल ताकि यह विफल हो सके।

अब मैक्रो परीक्षण

(defmacro test (x) 
    (let ((blah '#:jim)) 
    `(let ((,blah ,x)) 
     (print ,blah)))) 

CL-USER> (test 10) 

10 
10 
CL-USER> 

मीठा यह रास्ते से एक gensym वस्तु के रूप में की तरह इस्तेमाल किया जा सकता है ताकि के लिए।

मेरे लिए यह स्पष्ट रूप से समान परिणाम के साथ gensym से क्लीनर दिखता है। मुझे यकीन है कि मुझे एक महत्वपूर्ण जानकारी याद आ रही है इसलिए मेरा सवाल है, यह क्या है?

उत्तर

6

GENSYMMAKE-SYMBOL जैसा है। अंतर यह है कि GENSYM गिनती करके फैंसी नामकरण का समर्थन करता है -> इस प्रकार प्रतीकों के प्रकार के अद्वितीय नाम होते हैं, जो मैक्रो विस्तार में उदाहरण के लिए शब्दकोष होने पर थोड़ा आसान डिबगिंग करते हैं।

#:foo पाठक के लिए एक संकेत है।

तो आपके पास एक ऐसा कार्य है जो इन्हें और एक शाब्दिक नोटेशन बनाता है। ध्यान दें कि, जब *print-circle* सत्य है, तो किसी प्रकार की पहचान शायद एस-एक्सप्रेशन में संरक्षित हो: #(#1=#:FOO #1#)

आम तौर पर यह (a . b) और (cons 'a 'b), #(a b) और (vector 'a 'b) के समान है ... एक शाब्दिक डेटा और दूसरा एक रूप है जिसमें ('विपक्ष') ताजा वस्तुओं बनाएगा है।

यदि आप अपने मैक्रो को देखते हैं, तो मुख्य समस्या यह है कि इसका घोंसला उपयोग इससे समस्याएं पैदा कर सकता है। दोनों लेक्सिक या गतिशील रूप से।

  • स्पष्ट रूप से यह वही चर हो सकता है, जो रिबाउंड है।

  • गतिशील है, अगर यह एक विशेष चर रहा है यह भी पलटाव

मैक्रो विस्तार समय में एक उत्पन्न प्रतीक का उपयोग करना सुनिश्चित करें कि अलग और विस्तारित कोड बाइंडिंग का हिस्सा नहीं होता होगा हो सकता है।

+0

ओह हाँ, मैंने कैप्चर प्रभावों के बारे में सोचने में कभी भी बिताया नहीं था, जो स्पष्ट रूप से पूरे बिंदु..वोप्स! इस – Baggers

8

हर बार मैक्रो का विस्तार होता है, यह उसी प्रतीक का उपयोग करेगा।

(defmacro foo() `(quote #:x)) 
(defmacro bar() `(quote ,(gensym))) 

(eq (foo) (foo)) => t 
(eq (bar) (bar)) => nil 

Gensym एक नया प्रतीक हर बार यह मूल्यांकन किया जाता है पैदा करेगा, लेकिन जब यह पढ़ा जाता है तेज पेट के केवल एक नया प्रतीक पैदा करेगा।

तेज कॉलन का उपयोग करते समय समस्याएं पैदा होने की संभावना नहीं है, वहां कुछ दुर्लभ मामले हैं जहां इसका उपयोग करने से बग खोजने के लिए लगभग असंभव हो जाएगा।हमेशा gensym का उपयोग करके शुरू करने के लिए सुरक्षित होना बेहतर है।

यदि आप तेज कॉलन जैसे कुछ का उपयोग करना चाहते हैं, तो आपको लेटडा से लेट ओवर से defmacro! मैक्रो देखना चाहिए।

+0

के लिए धन्यवाद, इसे पकड़ लिया, मैं कब्जा करने की सोच के लिए एक डमी था। मैंने लैम्ब्डा को भी पढ़ा है, इसलिए मैं वास्तव में हेहेहेड था – Baggers