एक असहमतिपूर्ण राय: लिस्प की समलैंगिकता एक उपयोगी चीज से बहुत कम है जो कि लिस्प के अधिकांश प्रशंसकों को आप पर विश्वास करना होगा।
सिंटैक्टिक मैक्रोज़ को समझने के लिए, कंपाइलर्स को समझना महत्वपूर्ण है। कंपाइलर का काम मानव-पठनीय कोड को निष्पादन योग्य कोड में बदलना है। बहुत उच्च-स्तरीय परिप्रेक्ष्य से, इसके दो समग्र चरण होते हैं: पार्सिंग और कोड जनरेशन ।
पार्सिंग कोड को पढ़ने की प्रक्रिया है, इसे औपचारिक नियमों के एक सेट के अनुसार व्याख्या करना, और इसे एक पेड़ की संरचना में बदलना, जिसे आम तौर पर एएसटी (सार सिंटैक्स ट्री) के रूप में जाना जाता है। प्रोग्रामिंग भाषाओं के बीच सभी विविधता के लिए, यह एक उल्लेखनीय समानता है: अनिवार्य रूप से हर सामान्य-प्रयोजन प्रोग्रामिंग भाषा एक पेड़ की संरचना में होती है।
कोड पीढ़ी पार्सर की एएसटी को अपने इनपुट के रूप में लेता है, और इसे औपचारिक नियमों के आवेदन के माध्यम से निष्पादन योग्य कोड में बदल देता है। प्रदर्शन के दृष्टिकोण से, यह बहुत सरल कार्य है; कई उच्च-स्तरीय भाषा संकलक 75% या अधिक समय पार्सिंग पर खर्च करते हैं।
लिस्प के बारे में याद रखने वाली बात यह है कि यह बहुत, बहुत पुरानी है। प्रोग्रामिंग भाषाओं में, केवल फोरट्रान लिस्प की तुलना में पुराना है। दिन में वापस जाना, पार्सिंग (संकलन का धीमा हिस्सा) को एक अंधेरे और रहस्यमय कला माना जाता था। जॉन मैकार्थी के मूल पत्रों पर लिस्प के सिद्धांत (जब यह सिर्फ एक विचार था जिसे उन्होंने कभी नहीं सोचा था कि वास्तव में एक वास्तविक कंप्यूटर प्रोग्रामिंग भाषा के रूप में लागू किया जा सकता है) आधुनिक "एस-एक्सप्रेशंस" की तुलना में हर जगह हर चीज के लिए कुछ अधिक जटिल और अभिव्यंजक वाक्यविन्यास का वर्णन करता है। “संकेतन। यह बाद में आया, जब लोग वास्तव में इसे लागू करने की कोशिश कर रहे थे। क्योंकि पार्सिंग को अच्छी तरह से वापस नहीं समझा गया था, इसलिए उन्होंने मूल रूप से उस पर थपथपाया और एक होमोसेक्सुअल पेड़ की संरचना में सिंटेक्स को दबा दिया ताकि पार्सर का काम पूरी तरह से तुच्छ हो सके। अंतिम परिणाम यह है कि आपको (डेवलपर) बहुत कुछ करना होगा ' अपने कोड में सीधे औपचारिक एएसटी लिखकर इसके लिए काम करें। समरूपता "मैक्रोज़ को इतना आसान नहीं बनाती" जितना यह सब कुछ लिखना उतना ही कठिन बनाता है!
इसके साथ समस्या यह है कि, विशेष रूप से गतिशील टाइपिंग के साथ, एस-एक्सप्रेशंस के लिए बहुत अर्थपूर्ण जानकारी को अपने साथ ले जाना बहुत मुश्किल है। जब आपके सभी सिंटैक्स एक ही प्रकार के होते हैं (सूचियों की सूची), तो सिंटैक्स द्वारा प्रदान किए गए संदर्भ के तरीके में बहुत कुछ नहीं है, और इसलिए मैक्रो सिस्टम के साथ काम करने के लिए बहुत कम है।
कंपाइलर सिद्धांत 1960 के दशक के बाद से एक लंबा सफर तय कर चुका है जब लिस्प का आविष्कार किया गया था, और जब यह चीजें पूरी हुईं तो इसके दिन प्रभावशाली थे, वे अब आदिम दिखते हैं। एक आधुनिक मेटाप्रोग्रामिंग प्रणाली के एक उदाहरण के लिए, (उदास रूप से अल्पविकसित) बू भाषा पर एक नज़र है। बू को वैधानिक रूप से टाइप किया गया है, ऑब्जेक्ट-ओरिएंटेड और ओपन-सोर्स है, इसलिए प्रत्येक एएसटी नोड में एक अच्छी तरह से परिभाषित संरचना के साथ एक प्रकार है जो एक मैक्रो डेवलपर को कोड पढ़ सकता है। पायथन द्वारा प्रेरित भाषा में एक अपेक्षाकृत सरल वाक्यविन्यास है, जिसमें विभिन्न कीवर्ड हैं जो उनसे निर्मित वृक्ष संरचनाओं को आंतरिक अर्थ देते हैं, और इसके मेटाप्रोग्रामिंग में नए एएसटी नोड्स के निर्माण को सरल बनाने के लिए एक सहज quasiquote सिंटैक्स है।
यहाँ एक मैक्रो है जिसे मैंने कल बनाया था जब मुझे एहसास हुआ कि मैं एक ही पैटर्न को GUI कोड में विभिन्न स्थानों के एक समूह में लागू कर रहा हूं, जहां मैं BeginUpdate()
UI नियंत्रण पर कॉल करूंगा , एक try
ब्लॉक में एक अपडेट करूंगा , और फिर कॉल करूंगा EndUpdate()
:
macro UIUpdate(value as Expression):
return [|
$value.BeginUpdate()
try:
$(UIUpdate.Body)
ensure:
$value.EndUpdate()
|]
macro
आदेश, वास्तव में, है एक मैक्रो ही , एक है कि इनपुट के रूप में एक मैक्रो शरीर लेता है और मैक्रो कार्रवाई करने के लिए एक वर्ग उत्पन्न करता है। यह मैक्रो के नाम का उपयोग एक चर के रूप में करता है जो MacroStatement
एएसटी नोड के लिए खड़ा है जो मैक्रो इनवोकेशन का प्रतिनिधित्व करता है। द [| ... |] एक quasiquote ब्लॉक है, जो एएसटी उत्पन्न करता है जो कोड के भीतर और कोडिकोट ब्लॉक के अंदर स्थित है, $ प्रतीक "unquote" सुविधा प्रदान करता है, जो नोड में निर्दिष्ट है।
इसके साथ, यह लिखना संभव है:
UIUpdate myComboBox:
LoadDataInto(myComboBox)
myComboBox.SelectedIndex = 0
और इसका विस्तार करें:
myComboBox.BeginUpdate()
try:
LoadDataInto(myComboBox)
myComboBox.SelectedIndex = 0
ensure:
myComboBox.EndUpdate()
मैक्रो को व्यक्त करना इस तरह से सरल और अधिक सहज है क्योंकि यह एक लिस्प मैक्रो में होगा, क्योंकि डेवलपर की संरचना को MacroStatement
जानता है और जानता है कि कैसे Arguments
और Body
गुण काम करते हैं, और उस अंतर्निहित ज्ञान का उपयोग बहुत ही सहज ज्ञान युक्त अवधारणाओं को व्यक्त करने के लिए किया जा सकता है। मार्ग। यह अधिक सुरक्षित भी है, क्योंकि कंपाइलर की संरचना को जानता है MacroStatement
, और यदि आप किसी ऐसी चीज़ को कोड करने की कोशिश करते हैं जो ए के लिए मान्य नहीं है MacroStatement
, तो कंपाइलर इसे तुरंत पकड़ लेगा और त्रुटि की रिपोर्ट करेगा जब तक कि आपको पता न चले कि आपके ऊपर कुछ नहीं चल रहा है क्रम।
हास्केल, पायथन, जावा, स्काला आदि पर मैक्रो ग्राफ्टिंग करना मुश्किल नहीं है क्योंकि ये भाषाएं होमोसेक्सुअल नहीं हैं; यह मुश्किल है क्योंकि भाषाएं उनके लिए डिज़ाइन नहीं की गई हैं, और यह सबसे अच्छा काम करता है जब आपकी भाषा एएसटी पदानुक्रम को एक मैक्रो सिस्टम द्वारा जांच और हेरफेर करने के लिए जमीन से डिज़ाइन किया गया है। जब आप एक ऐसी भाषा के साथ काम कर रहे होते हैं, जिसे शुरू से ही मेटाप्रोग्रामिंग के साथ डिजाइन किया गया था, तो मैक्रोज़ के साथ काम करना बहुत सरल और आसान है!