खोज…
वाक्य - विन्यास
-
'
Macroexpand उदाहरण में प्रयुक्त प्रतीक के लिए बस वाक्यात्मक चीनी हैquote
ऑपरेटर। आप इसके बजाय(macroexpand (quote (infix 1 + 2)))
लिख सकते थे।
टिप्पणियों
मैक्रोज़ केवल फ़ंक्शंस हैं जो कंपाइल टाइम पर चलते हैं, यानी रीड-इवल-प्रिंट-लूप में eval
स्टेप के दौरान।
रीडर मैक्रो मैक्रो का एक और रूप है जो कि संकलन समय के बजाय रीड टाइम पर विस्तारित हो जाता है।
मैक्रो को परिभाषित करते समय सबसे अच्छा अभ्यास।
- अल्फा-रिनेमिंग, चूंकि मैक्रो का विस्तार है बाध्यकारी नाम संघर्ष पैदा हो सकता है। मैक्रो का उपयोग करते समय हल करने के लिए बाइंडिंग संघर्ष बहुत सहज नहीं है। यही कारण है कि, जब भी कोई मैक्रो स्कोप में बाइंडिंग जोड़ता है, तो प्रत्येक सिंबल के अंत में
#
का उपयोग करना अनिवार्य होता है।
सरल इन्फिक्स मैक्रो
क्लोजर उपसर्ग संकेतन का उपयोग करता है, अर्थात्: ऑपरेटर अपने ऑपरेंड से पहले आता है।
उदाहरण के लिए, दो संख्याओं का एक सरल योग होगा:
(+ 1 2) ;; => 3
मैक्रों आपको क्लोजर भाषा में एक निश्चित डिग्री तक हेरफेर करने की अनुमति देते हैं। उदाहरण के लिए, आप एक मैक्रो लागू कर सकते हैं जो आपको infix संकेतन में कोड लिखने देता है (जैसे, 1 + 2
):
(defmacro infix [first-operand operator second-operand]
"Converts an infix expression into a prefix expression"
(list operator first-operand second-operand))
चलो ऊपर कोड क्या करता है:
-
defmacro
एक विशेष रूप आप मैक्रो निर्धारित करने के लिए इस्तेमाल करते हैं। -
infix
उस स्थूल का नाम है जिसे हम परिभाषित कर रहे हैं। -
[first-operand operator second-operand]
वे पैरामीटर हैं जिन्हें यह मैक्रो प्राप्त होने की उम्मीद करता है। -
(list operator first-operand second-operand)
हमारे स्थूल का शरीर है। यह केवलinfix
मैक्रो को दिए गए मापदंडों के मूल्यों के साथ एकlist
बनाता है और रिटर्न देता है।
defmacro
एक विशेष रूप है क्योंकि यह अन्य क्लोजर निर्माणों की तुलना में थोड़ा अलग व्यवहार करता है: इसके मापदंडों का तुरंत मूल्यांकन नहीं किया जाता है (जब हम मैक्रो कहते हैं)। यह वही है जो हमें कुछ लिखने की अनुमति देता है:
(infix 1 + 2)
;; => 3
infix
मैक्रो 1 + 2
तर्कों को (+ 1 2)
में विस्तारित करेगा, जो कि एक मान्य क्लॉज्योर फॉर्म है जिसका मूल्यांकन किया जा सकता है।
यदि आप देखना चाहते हैं कि infix
मैक्रो क्या उत्पन्न करता है, तो आप macroexpand
ऑपरेटर का उपयोग कर सकते हैं:
(macroexpand '(infix 1 + 2))
;; => (+ 1 2)
macroexpand
, जैसा कि इसके नाम से निहित है, मैक्रो का विस्तार करेगा (इस मामले में, यह infix
मैक्रो का उपयोग करके 1 + 2
को (+ 1 2)
) लेकिन मैक्रो विस्तार के परिणाम का मूल्यांकन करने की अनुमति नहीं देगा क्लोजर का दुभाषिया।
सिंटैक्स उद्धृत करना और अनुत्तरित करना
मानक पुस्तकालय से उदाहरण ( core.clj: 807 ):
(defmacro and
"Evaluates exprs one at a time, from left to right. If a form
returns logical false (nil or false), and returns that value and
doesn't evaluate any of the other expressions, otherwise it returns
the value of the last expr. (and) returns true."
{:added "1.0"}
([] true)
([x] x)
([x & next]
`(let [and# ~x]
(if and# (and ~@next) and#))))
-
`
सिंटैक्स-उद्धरण कहा जाता है(quote)
तरह है, लेकिन पुनरावर्ती: यह कारण बनता है(let …)
,(if …)
, आदि मैक्रो विस्तार के दौरान मूल्यांकन करने के लिए नहीं, लेकिन आउटपुट के रूप में है -
~
उर्फ एकल वाक्य-उद्धरण रूप के अंदर एकल रूप के लिए वाक्यविन्यास-उद्धरण रद्द करता है। तो स्थूल का विस्तार करते समयx
का मान आउटपुट किया जाता है (बजायx
प्रतीक के आउटपुट के) -
~@
aka unquote-splicing, unquote की तरह है लेकिन सूची तर्क लेता है और इसे विस्तारित करता है, प्रत्येक सूची आइटम को अलग रूप में -
#
नाम संघर्ष को रोकने के लिए प्रतीकों को अद्वितीय आईडी देता है। यह सिंटैक्स-उद्धृत अभिव्यक्ति के अंदर एक ही प्रतीक के लिए एक ही आईडी को जोड़ता है, इसलिएand#
अंदरlet
and#
अंदरif
यह नाम होगा