यहाँ एक मैं डिबगिंग के लिए उपयोग कर रहा हूँ (क्लोजर में):
user=> (defmacro print-var [varname] `(println ~(name varname) "=" ~varname))
#'user/print-var
=> (def x (reduce * [1 2 3 4 5]))
#'user/x
=> (print-var x)
x = 120
nil
मुझे C ++ में एक हाथ से लुढ़का हुआ हैश-टेबल से निपटना पड़ा, जहां get
विधि ने एक गैर-कॉन्स्टेंस स्ट्रिंग को एक तर्क के रूप में लिया, जिसका अर्थ है कि मैं इसे शाब्दिक रूप से नहीं कह सकता। इससे निपटने के लिए आसान बनाने के लिए, मैंने निम्नलिखित कुछ लिखा:
#define LET(name, value, body) \
do { \
string name(value); \
body; \
assert(name == value); \
} while (false)
जबकि इस समस्या की तरह कुछ भी लिस्प में आने की संभावना नहीं है, मुझे यह विशेष रूप से अच्छा लगता है कि आपके पास दो बार अपने तर्क का मूल्यांकन नहीं करने वाले मैक्रोज़ हो सकते हैं, उदाहरण के लिए एक वास्तविक ले -बाइंडिंग शुरू करके । (स्वीकार किया, यहाँ मैं इसके आसपास मिल सकता था)।
मैं सामान को लपेटने की भयानक बदसूरत हैक का भी सहारा do ... while (false)
लेता हूं ताकि आप इसे इफ़े के हिस्से में उपयोग कर सकें और अभी भी उम्मीद के मुताबिक अन्य भाग काम कर सकें। आपको लिस्प में इसकी आवश्यकता नहीं है, जो स्ट्रिंग्स (या टोकन अनुक्रमों के बजाय, सी और सी ++ के मामले में) के बजाय सिंटैक्स पेड़ों पर काम करने वाले मैक्रोज़ का एक कार्य है, जो तब पार्सिंग से गुजरता है।
कुछ अंतर्निहित थ्रेडिंग मैक्रोज़ हैं जिनका उपयोग आपके कोड को पुनर्गठित करने के लिए किया जा सकता है जैसे कि यह अधिक सफाई से पढ़ता है ('थ्रेडिंग' जैसे 'अपने कोड को एक साथ बोना', समानता नहीं)। उदाहरण के लिए:
(->> (range 6) (filter even?) (map inc) (reduce *))
यह पहला रूप लेता है (range 6)
, और इसे अगले रूप का अंतिम तर्क बनाता है (filter even?)
, जो बदले में अगले रूप का अंतिम तर्क बनाता है और इसी तरह, जैसे कि ऊपर फिर से लिखा जाता है।
(reduce * (map inc (filter even? (range 6))))
मुझे लगता है कि पहला बहुत अधिक स्पष्ट रूप से पढ़ता है: "इन आंकड़ों को लें, इसे इसके लिए करें, फिर ऐसा करें, फिर दूसरे को करें और हम कर रहे हैं", लेकिन यह व्यक्तिपरक है; कुछ ऐसा है जो उद्देश्यपूर्ण रूप से सत्य है कि आप अपने द्वारा निष्पादित अनुक्रम में संचालन को पढ़ते हैं (आलस्य को अनदेखा करते हुए)।
एक संस्करण भी है जो पिछले फॉर्म को पहले (अंतिम की बजाय) तर्क के रूप में सम्मिलित करता है। एक उपयोग का मामला अंकगणित है:
(-> 17 (- 2) (/ 3))
"17 लेने, 2 घटाना और 3 से विभाजित" के रूप में पढ़ता है।
अंकगणित की बात करें, तो आप एक मैक्रो लिख सकते हैं, जो इन्फिक्स नोटेशन पार्सिंग करता है, ताकि आप उदाहरण के लिए कह सकें (infix (17 - 2) / 3)
और यह थूक देगा, (/ (- 17 2) 3)
जिसमें कम पठनीय होने का नुकसान है और एक वैध लिस्प अभिव्यक्ति होने का फायदा है। यह डीएसएल / डेटा सबलंगेज हिस्सा है।