संक्षिप्त उत्तर देने के लिए, मैक्रोज़ का उपयोग कॉमन लिस्प या डोमेन स्पेसिफिक लैंग्वेज (डीएसएल) के लिए भाषा सिंटैक्स एक्सटेंशन को परिभाषित करने के लिए किया जाता है। ये भाषाएं मौजूदा लिस्प कोड में ही अंतर्निहित हैं। अब, डीएसएल में लिस्प के समान सिंटेक्स हो सकता है (जैसे कॉमन लिस्प के लिए पीटर नॉर्विग के प्रोलोग इंटरप्रेटर ) या पूरी तरह से अलग (जैसे क्लोज्योर के लिए इन्फिक्स नोटेशन मैथ )।
यहाँ एक और अधिक ठोस उदाहरण है:
पायथन में भाषा में निर्मित सूची समझ है। यह एक सामान्य मामले के लिए एक सरल वाक्यविन्यास देता है। रेखा
divisibleByTwo = [x for x in range(10) if x % 2 == 0]
एक सूची देता है जिसमें 0 और 9 के बीच सभी संख्याएँ होती हैं। पाइथन 1.5 दिनों में वापस ऐसा कोई सिंटैक्स नहीं था; आप इस तरह से कुछ और उपयोग करेंगे:
divisibleByTwo = []
for x in range( 10 ):
if x % 2 == 0:
divisibleByTwo.append( x )
ये दोनों कार्यात्मक रूप से समतुल्य हैं। चलो अविश्वास के हमारे निलंबन का आह्वान करते हैं और दिखावा करते हैं कि लिस्प के पास एक बहुत ही सीमित लूप मैक्रो है जो बस पुनरावृत्ति करता है और सूची बोध के बराबर करने का कोई आसान तरीका नहीं है।
लिस्प में आप निम्नलिखित लिख सकते हैं। मुझे यह ध्यान देना चाहिए कि यह आकस्मिक उदाहरण पायथन कोड के समान है जिसे लिस्प कोड का अच्छा उदाहरण नहीं है।
;; the following two functions just make equivalent of Python's range function
;; you can safely ignore them unless you are running this code
(defun range-helper (x)
(if (= x 0)
(list x)
(cons x (range-helper (- x 1)))))
(defun range (x)
(reverse (range-helper (- x 1))))
;; equivalent to the python example:
;; define a variable
(defvar divisibleByTwo nil)
;; loop from 0 upto and including 9
(loop for x in (range 10)
;; test for divisibility by two
if (= (mod x 2) 0)
;; append to the list
do (setq divisibleByTwo (append divisibleByTwo (list x))))
इससे पहले कि मैं आगे बढ़ूं, मुझे बेहतर तरीके से बताना चाहिए कि मैक्रो क्या है। यह एक कोड द्वारा कोड पर किया गया परिवर्तन है । यही है, कोड का एक टुकड़ा, दुभाषिया (या संकलक) द्वारा पढ़ा जाता है, जो कोड में एक तर्क के रूप में लेता है, हेरफेर करता है और परिणाम देता है, जो तब इन-प्लेस में चलाया जाता है।
बेशक, बहुत सारे टाइपिंग और प्रोग्रामर आलसी हैं। तो हम सूची बोध करने के लिए DSL को परिभाषित कर सकते हैं। वास्तव में, हम पहले से ही एक मैक्रो का उपयोग कर रहे हैं (लूप मैक्रो)।
लिस्प विशेष सिंटैक्स रूपों के एक जोड़े को परिभाषित करता है। उद्धरण ( '
) इंगित करता है कि अगला टोकन एक शाब्दिक है। क्यूसिकोट या बैकटिक ( `
) इंगित करता है कि अगला टोकन पलायन के साथ एक शाब्दिक है। अल्पविराम ऑपरेटर द्वारा पलायन का संकेत दिया जाता है। शाब्दिक '(1 2 3)
है पायथन के बराबर [1, 2, 3]
। आप इसे दूसरे वेरिएबल में असाइन कर सकते हैं या इसका इस्तेमाल कर सकते हैं। आप `(1 2 ,x)
पायथन के समतुल्य के रूप में सोच सकते हैं [1, 2, x]
जहां x
पहले से परिभाषित एक चर है। यह सूची नोटेशन मैक्रो में जाने वाले जादू का हिस्सा है। दूसरा भाग लिस्प रीडर है, जो समझदारी से मैक्रोज़ को कोड के लिए स्थानापन्न करता है, लेकिन इसका सबसे अच्छा विवरण नीचे दिया गया है:
इसलिए हम एक मैक्रो को परिभाषित कर सकते हैं lcomp
(सूची समझ के लिए छोटा)। यह वाक्य रचना बिल्कुल उस अजगर की तरह होगा जिसका हमने उदाहरण में प्रयोग किया है [x for x in range(10) if x % 2 == 0]
-(lcomp x for x in (range 10) if (= (% x 2) 0))
(defmacro lcomp (expression for var in list conditional conditional-test)
;; create a unique variable name for the result
(let ((result (gensym)))
;; the arguments are really code so we can substitute them
;; store nil in the unique variable name generated above
`(let ((,result nil))
;; var is a variable name
;; list is the list literal we are suppose to iterate over
(loop for ,var in ,list
;; conditional is if or unless
;; conditional-test is (= (mod x 2) 0) in our examples
,conditional ,conditional-test
;; and this is the action from the earlier lisp example
;; result = result + [x] in python
do (setq ,result (append ,result (list ,expression))))
;; return the result
,result)))
अब हम कमांड लाइन पर निष्पादित कर सकते हैं:
CL-USER> (lcomp x for x in (range 10) if (= (mod x 2) 0))
(0 2 4 6 8)
बहुत साफ, हुह? अब यह वहाँ बंद नहीं करता है। आपके पास एक तंत्र, या एक तूलिका है, यदि आप चाहें। आपके पास कोई भी वाक्यविन्यास हो सकता है जिसे आप संभवतः चाहते हैं। जैसे पायथन या C # का with
सिंटैक्स। या .NET का LINQ सिंटेक्स। अंत में, यह वही है जो लोगों को लिस्प - परम लचीलेपन के लिए आकर्षित करता है।