प्रतीकों को पैकेज में प्रशिक्षित किया जा सकता है या नहीं। एक पैकेज में प्रशिक्षित एक प्रतीक देखा और पाया जा सकता है। पैकेज में एक अनियंत्रित प्रतीक नहीं देखा जा सकता है। किसी निश्चित नाम का केवल एक प्रतीक पैकेज में हो सकता है। केवल एक प्रतीक CL-USER::FRED
है।
आप लिखें:
तो जहाँ तक मुझे पता है uninterned प्रतीकों प्रतीक है जिसके लिए मूल्यांकनकर्ता आंतरिक रूप से बाध्यकारी प्रतीक-डेटा बनाने शामिल नहीं कर रहे हैं।
यह गलत है। अनियंत्रित प्रतीकों प्रतीक हैं जो किसी भी पैकेज में इंटर्न नहीं हैं। अन्यथा वे पूरी तरह से ठीक हैं। प्रशिक्षित का अर्थ है पैकेज के रजिस्ट्री में इसके प्रतीकों के लिए पंजीकृत है।
एस अभिव्यक्ति पाठक प्रतीक नाम और दौरान पैकेज पढ़ने प्रतीकों की पहचान करने के लिए उपयोग करता है। यदि ऐसा कोई प्रतीक नहीं है, तो यह इंटर्न किया गया है। यदि कोई है, तो यह वापस आ गया है।
(read-from-string "FOO") -> symbol `FOO`
दूसरी बार:
(read-from-string "FOO") -> symbol `FOO`
यह हमेशा एक ही प्रतीक FOO
है
पाठक अप वर्तमान पैकेज में यहां उनके नाम से प्रतीक देखो, नहीं करता है।
(eq (read-from-string "FOO") (read-from-string "FOO")) -> T
#:FOO
नाम FOO
के साथ एक uninterned प्रतीक के लिए वाक्य रचना है। यह किसी भी पैकेज में प्रशिक्षित नहीं है। यदि पाठक इस वाक्यविन्यास को देखता है, तो यह एक नया अनियंत्रित प्रतीक बनाता है।
(read-from-string "#:FOO") -> new symbol `FOO`
दूसरी बार:
(read-from-string "#:FOO") -> new symbol `FOO`
दोनों प्रतीकों अलग हैं। उनके पास एक ही नाम है, लेकिन वे अलग-अलग डेटा ऑब्जेक्ट्स हैं। पैकेजों की तुलना में प्रतीकों के लिए कोई अन्य रजिस्ट्री नहीं है।
(eq (read-from-string "#:FOO") (read-from-string "#:FOO")) -> NIL
इस प्रकार अपने मामले (LET ((#:G4315 1)) (PRINT (INCF #:G4315)))
में, uninterned प्रतीकों विभिन्न वस्तुओं रहे हैं। दूसरा तो एक अलग चर है।
कॉमन लिस्प डेटा मुद्रित करने के लिए एक तरीका है, ताकि पहचान मुद्रण के दौरान संरक्षित है/पढ़ने:
CL-USER 59 > (macroexpand-1 '(test-macro))
(LET ((#:G1996 1)) (PRINT (INCF #:G1996)))
T
CL-USER 60 > (setf *print-circle* t)
T
CL-USER 61 > (macroexpand-1 '(test-macro))
(LET ((#1=#:G1998 1)) (PRINT (INCF #1#)))
T
अब आप देख मुद्रित रों अभिव्यक्ति पहले प्रतीक के लिए एक लेबल #1=
है । इसके बाद में यह वही चर संदर्भित करता है। इसे वापस पढ़ा जा सकता है और प्रतीक पहचान संरक्षित हैं - भले ही पाठक पैकेज को देखकर प्रतीक की पहचान नहीं कर सके।
इस प्रकार मैक्रो एक रूप बनाता है, जहां केवल एक प्रतीक उत्पन्न होता है। जब हम उस फॉर्म को प्रिंट करते हैं और इसे वापस पढ़ना चाहते हैं, तो हमें यह सुनिश्चित करना होगा कि अनियंत्रित प्रतीकों की पहचान संरक्षित है। *print-circle*
के साथ प्रिंटिंग T
पर सेट करने में मदद करता है।
प्र: हम GENSYM
(प्रतीक उत्पन्न) का उपयोग करके मैक्रो में uninterned उत्पन्न प्रतीकों का उपयोग करते हैं?
इस तरह हम अद्वितीय नए प्रतीक प्राप्त कर सकते हैं जो कोड में अन्य प्रतीकों से टकराव नहीं करते हैं। उन्हें gensym
फ़ंक्शन द्वारा नाम मिलता है - आमतौर पर अंत में एक संख्याबद्ध संख्या के साथ। चूंकि वे ताजा नए प्रतीक हैं जो किसी भी पैकेज में प्रशिक्षित नहीं हैं, इसलिए कोई नामकरण संघर्ष नहीं हो सकता है।
CL-USER 66 > (gensym)
#:G1999
CL-USER 67 > (gensym)
#:G2000
CL-USER 68 > (gensym "VAR")
#:VAR2001
CL-USER 69 > (gensym "PERSON")
#:PERSON2002
CL-USER 70 > (gensym)
#:G2003
CL-USER 71 > (describe *)
#:G2003 is a SYMBOL
NAME "G2003"
VALUE #<unbound value>
FUNCTION #<unbound function>
PLIST NIL
PACKAGE NIL <------- no package
अगर मैं अपने स्पष्टीकरण सही ढंग से समझ में आया, 'gensym' अभी भी सही ढंग से काम करेंगे तो भी यह प्रतीक के नाम करने के लिए एक गिना संख्या जोड़ नहीं था, यानी अगर यह एक ही नाम के साथ हर बार एक uninterned प्रतीक लौटे इसे (उसी तर्क के साथ) कहा जाता है। क्या वो सही है? यदि हां: तो यह संख्या क्यों जोड़ता है? ताकि कोई आसानी से बता सके कि कौन से प्रतीक समान हैं और जो 'मैक्रो-विस्तार' के आउटपुट में नहीं हैं? – sepp2k
@ sepp2k: सही, संख्या केवल यह पता लगाने में आसान है कि अनियंत्रित प्रतीक अलग हैं और जो समान हो सकता है। यह एक डीबगिंग सहायता है। पहले लिस्प बोलीभाषाओं में (पैकेज के बिना) यह अधिक महत्वपूर्ण हो सकता था। –
बहुत बहुत धन्यवाद। * प्रिंट-सर्कल * स्पष्टीकरण वास्तव में यह समझने में सहायक होता है कि यह कैसे काम करता है। और अनियंत्रित प्रतीकों के बारे में कुछ स्पष्टीकरण के लिए भी धन्यवाद। – JustAnotherCurious