एक डेकोरेटर मूल रूप से केवल एक फ़ंक्शन है ।
आम लिस्प में उदाहरण:
(defun attributes (keywords function)
(loop for (key value) in keywords
do (setf (get function key) value))
function)
फ़ंक्शन के ऊपर एक प्रतीक है (जो द्वारा लौटा दिया जाएगा DEFUN
) और हमने विशेषताओं को प्रतीक की संपत्ति सूची में डाल दिया ।
अब हम इसे एक फंक्शन परिभाषा के आसपास लिख सकते हैं:
(attributes
'((version-added "2.2")
(author "Rainer Joswig"))
(defun foo (a b)
(+ a b))
)
यदि हम पाइथन में एक फैंसी सिंटैक्स जोड़ना चाहते हैं, तो हम एक पाठक मैक्रो लिखते हैं । एक पाठक मैक्रो हमें एस-एक्सप्रेशन सिंटैक्स के स्तर पर प्रोग्राम करने की अनुमति देता है:
(set-macro-character
#\@
(lambda (stream char)
(let ((decorator (read stream))
(arg (read stream))
(form (read stream)))
`(,decorator ,arg ,form))))
हम फिर लिख सकते हैं:
@attributes'((version-added "2.2")
(author "Rainer Joswig"))
(defun foo (a b)
(+ a b))
लिस्प पाठक ऊपर पढ़ता है:
(ATTRIBUTES (QUOTE ((VERSION-ADDED "2.2")
(AUTHOR "Rainer Joswig")))
(DEFUN FOO (A B) (+ A B)))
अब हमारे पास कॉमन लिस्प में डेकोरेटर्स का एक रूप है ।
मैक्रोज़ और रीडर मैक्रोज़ का मेल।
वास्तव में मैं मैक्रो का उपयोग करके वास्तविक कोड में उपरोक्त अनुवाद करूँगा, न कि किसी फ़ंक्शन का।
(defmacro defdecorator (decorator arg form)
`(progn
,form
(,decorator ,arg ',(second form))))
(set-macro-character
#\@
(lambda (stream char)
(declare (ignore char))
(let* ((decorator (read stream))
(arg (read stream))
(form (read stream)))
`(defdecorator ,decorator ,arg ,form))))
उपयोग एक ही पाठक मैक्रो के साथ ऊपर है। लाभ यह है कि लिस्प संकलक अभी भी इसे तथाकथित शीर्ष-स्तरीय रूप में देखता है - * फ़ाइल संकलक विशेष रूप से शीर्ष-स्तरीय रूपों का इलाज करता है, उदाहरण के लिए यह संकलन-समय के वातावरण में उनके बारे में जानकारी जोड़ता है । ऊपर के उदाहरण में हम देख सकते हैं कि मैक्रो स्रोत कोड में दिखता है और नाम को निकालता है।
लिस्प पाठक उपरोक्त उदाहरण में पढ़ता है:
(DEFDECORATOR ATTRIBUTES
(QUOTE ((VERSION-ADDED "2.2")
(AUTHOR "Rainer Joswig")))
(DEFUN FOO (A B) (+ A B)))
जो तब मैक्रो में विस्तारित हो जाता है:
(PROGN (DEFUN FOO (A B) (+ A B))
(ATTRIBUTES (QUOTE ((VERSION-ADDED "2.2")
(AUTHOR "Rainer Joswig")))
(QUOTE FOO)))
मैक्रोज़ रीडर मैक्रोज़ से बहुत अलग हैं ।
मैक्रोज़ स्रोत कोड को पास कर लेते हैं, वे जो चाहें कर सकते हैं और फिर स्रोत कोड वापस कर सकते हैं। इनपुट स्रोत को वैध लिस्प कोड की आवश्यकता नहीं है। यह कुछ भी हो सकता है और इसे पूरी तरह से अलग लिखा जा सकता है। परिणाम तब मान्य लिस्प कोड होना चाहिए। लेकिन अगर उत्पन्न कोड एक मैक्रो का भी उपयोग कर रहा है, तो मैक्रो कॉल में एम्बेडेड कोड का सिंटैक्स फिर से एक अलग सिंटैक्स हो सकता है। एक सरल उदाहरण: कोई गणित मैक्रो लिख सकता है जो किसी प्रकार के गणितीय वाक्यविन्यास को स्वीकार करेगा:
(math y = 3 x ^ 2 - 4 x + 3)
अभिव्यक्ति y = 3 x ^ 2 - 4 x + 3
वैध लिस्प कोड नहीं है, लेकिन मैक्रो उदाहरण के लिए इसे पार्स कर सकता है और इस तरह वैध लिस्प कोड लौटा सकता है:
(setq y (+ (* 3 (expt x 2))
(- (* 4 x))
3))
लिस्प में मैक्रोज़ के कई अन्य उपयोग के मामले हैं।