यहां एक आरेख है जो प्रतीक a
और (setq a '(1 2))
के बाद इसका मान दर्शाता है। बक्से प्राथमिक डेटा संरचनाएं (प्रतीकों और विपक्ष) हैं और तीर पॉइंटर्स हैं (जहां डेटा का एक टुकड़ा दूसरे संदर्भ देता है)। (मैं एक छोटे से सरल बनाने रहा हूँ।)
symbol cons cons
+-------+----------+ +------+------+ +------+------+
|name: |variable: | |car: |cdr: | |car: |cdr: |
| a | | | | 1 | | | | 2 | nil |
+-------+----|-----+ +------+--|---+ +------+------+
| ↑ | ↑
+-------------+ +-------+
अभिव्यक्ति '(1 2)
सही पर दो conses है, जो एक दो तत्व सूची में शामिल बनाता है। अभिव्यक्ति (setq a '(1 2))
प्रतीक a
बनाता है यदि यह अस्तित्व में नहीं है, तो उसके "परिवर्तनीय स्लॉट" (भाग में प्रतीक का मूल्य शामिल है) बनाता है जो नव निर्मित सूची को इंगित करता है। setq
एक अंतर्निहित मैक्रो है, और (setq a '(1 2))
(set 'a '(1 2))
के लिए शॉर्टेंड है। set
का पहला तर्क संशोधित करने का प्रतीक है और दूसरा तर्क प्रतीक के परिवर्तनीय स्लॉट को सेट करने का मान है।
(add-to-list 'a 3)
(set 'a (cons 3 a))
के बराबर है, क्योंकि 3 सूची में नहीं है। यह अभिव्यक्ति चार चीजें करता है:
- एक नया विपक्ष सेल बनाएं।
- नया विपक्ष सेल का कार फ़ील्ड पर सेट करें।
- नया विपक्ष सेल का सीडीआर फ़ील्ड
a
के पूर्व (और अभी भी वर्तमान) मान पर सेट करें (यानी a
के चर स्लॉट की सामग्री कॉपी करें)।
- नए विपक्षी सेल में
a
के परिवर्तनीय स्लॉट सेट करें।
है कि कॉल करने के बाद, डेटा संरचनाओं इस तरह शामिल देखो:
symbol cons cons cons
+-------+----------+ +------+--|---+ +------+------+ +------+------+
|name: |variable: | |car: |cdr: | |car: |cdr: | |car: |cdr: |
| a | | | | 3 | | | | 1 | | | | 2 | nil |
+-------+----|-----+ +------+--|---+ +------+--|---+ +------+------+
| ↑ | ↑ | ↑
+-------------+ +-------+ +-------+
setcar
करने के लिए कॉल किसी भी नए डेटा संरचना का निर्माण नहीं करता है, और प्रतीक a
पर लेकिन इस पर कार्रवाई नहीं करता है इसके मूल्य, जो विपक्ष सेल जिसका car
वर्तमान में शामिल 3. (setcar a 4)
के बाद, डेटा संरचनाओं इस तरह दिखना है:
symbol cons cons cons
+-------+----------+ +------+--|---+ +------+------+ +------+------+
|name: |variable: | |car: |cdr: | |car: |cdr: | |car: |cdr: |
| a | | | | 4 | | | | 1 | | | | 2 | nil |
+-------+----|-----+ +------+--|---+ +------+--|---+ +------+------+
| ↑ | ↑ | ↑
+-------------+ +-------+ +-------+
push
है एक मैक्रो; यहां, (push 5 a)
(set 'a (cons 5 a))
के बराबर है।
setq
और push
मैक्रो नहीं है (setq
एक "विशेष रूप" है, जो जहाँ तक हम यहाँ चिंतित हैं के रूप में एक मैक्रो जिसकी परिभाषा दुभाषिया में बनाया गया है और लिस्प में उपलब्ध नहीं कराया गया है इसका मतलब है)। मैक्रोज़ को उनके तर्कों का मूल्यांकन नहीं किया जाता है और उन्हें विस्तारित करना चुन सकता है या नहीं। set
, setcar
और add-to-list
कार्य हैं, जो उनके तर्कों का मूल्यांकन करते हैं। एक प्रतीक का मूल्यांकन करना इसके परिवर्तनीय स्लॉट की सामग्री देता है, उदा। प्रारंभिक (setq a '(1 2))
के बाद प्रतीक a
का मान उस सेल कक्ष है जिसका कार 1
है।
आप अभी भी उलझन में कर रहे हैं, मैं (setq b a)
के साथ प्रयोग करने की सलाह देते हैं और अपने आप के लिए देख रहा है जो अभिव्यक्ति की b
संशोधित जब आप a
पर (जो कि प्रतीक a
पर कार्रवाई) और जो कार्य नहीं है (जो कि प्रतीक a
के मूल्य पर कार्य करें)।
क्या आप बता सकते हैं कि कार्यान्वयन को देखे बिना अपने दस्तावेज़ से पूरी तरह से मैक्रो या फ़ंक्शन कुछ है या नहीं? – Tom
@ टॉम प्रलेखन आमतौर पर बताता है कि पहली पंक्ति में तुरंत (पुश - पुश के लिए \ 'cl.el''' में लिस्प मैक्रो है)। –
हां, लेकिन सेटकार के बारे में क्या? आप दस्तावेज़ से कैसे जानते हैं कि यह इसके तर्क का मूल्यांकन नहीं करता है? – Tom