एक "कोड की भाषा की जागरूकता" के लिए, वहाँ कोई बेहतर रहा है लिस्प और इसकी मैक्रो सुविधा से विशेष रूप से देखा गया है - विशेष रूप से, आम लिस्प। लेकिन व्यापार यह है कि ज्यादातर समय किसी ऑब्जेक्ट का प्रकार संकलन समय या मैक्रोएक्सप्शन समय पर ज्ञात नहीं होता है। शाब्दिक के लिए, प्रकार ज्ञात हैं, इसलिए आप आक्रामक मैक्रोज़ के उदाहरण पा सकते हैं जो यह देखने के लिए परीक्षण करते हैं कि कोई ऑब्जेक्ट एक शाब्दिक है और यदि ऐसा है, तो इसे एक तरह से इलाज करें - शायद इसके प्रकार के आधार पर - और अन्यथा ज्ञात चर तैयार करें रन-टाइम प्रकार निरीक्षण के लिए।
यहां एक उदाहरण है जिसे मैंने कई वर्षों पहले CLLIB लाइब्रेरी (CLOCC लाइब्रेरी का हिस्सा) से अनुकूलित किया है। लक्ष्य उन कार्यों को प्रदान करना है जो किसी अन्य स्ट्रिंग के साथ किसी अन्य स्ट्रिंग के उपसर्ग स्ट्रिंग को काट लेंगे। उपसर्ग मैक्रोएक्सप्शन समय पर ज्ञात हो सकता है या ऐसा नहीं हो सकता है। यदि ऐसा है, तो हम एक अनुकूलन कर सकते हैं: उपसर्ग की लंबाई पहले गणना करें और इसे एक शाब्दिक के रूप में एम्बेड करें, ताकि यह प्रत्येक कॉल पर जेनरेट किए गए फ़ंक्शन पर पुन: संकलित न हो। मैक्रो पहले पर चुनौतीपूर्ण है, लेकिन वास्तविक जेनरेट कोड छोटा है।
(defmacro after-prefix-core (comparison-op prefix string &optional length)
"Similar to cllib:string-beg-with-cs."
(flet ((chop (prefix prefix-length string string-length)
`(when (and (>= ,string-length ,prefix-length)
(,comparison-op ,prefix ,string :end2 ,prefix-length))
(subseq ,string ,prefix-length ,string-length))))
(let* ((gstring (gensym "STRING-"))
(gstring-length (gensym "STRING-LENGTH-")))
`(let* ((,gstring ,string)
(,gstring-length ,(or length `(length ,gstring))))
,(if (stringp prefix)
;; Constant -- length known at expansion time.
(let ((prefix-length (length prefix)))
(chop prefix prefix-length gstring gstring-length))
;; Other form -- length not known at expansion time.
(let ((gprefix (gensym "PREFIX-"))
(gprefix-length (gensym "PREFIX-LENGTH-")))
`(let* ((,gprefix ,prefix)
(,gprefix-length (length ,gprefix)))
,(chop gprefix gprefix-length gstring gstring-length))))))))
(defmacro after-prefix (prefix string &optional length)
"Similar to cllib:string-beg-with."
`(after-prefix-core string-equal ,prefix ,string ,length))
(defmacro after-prefix-cs (prefix string &optional length)
"Similar to cllib:string-beg-with-cs."
`(after-prefix-core string= ,prefix ,string ,length))
रूप
(if (stringp prefix)
बीच में
देखते हैं? यह macroexpansion समय पर पहला तर्क का निरीक्षण कर रहा है और इस पर निर्भर करता है कि तर्क एक शाब्दिक या प्रतीक है, इसका प्रकार ज्ञात हो सकता है या नहीं।यदि प्रकार एक प्रतीक है, तो हम मानते हैं कि हमें किसी अन्य मूल्य पर इंगित करने वाले चर के रूप में पुनर्विचार करने के लिए रन टाइम तक प्रतीक्षा करनी चाहिए।
(LET* ((#:STRING-5340 BAR) (#:STRING-LENGTH-5341 (LENGTH #:STRING-5340)))
(LET* ((#:PREFIX-5342 FOO) (#:PREFIX-LENGTH-5343 (LENGTH #:PREFIX-5342)))
(WHEN
(AND (>= #:STRING-LENGTH-5341 #:PREFIX-LENGTH-5343)
(STRING-EQUAL #:PREFIX-5342 #:STRING-5340 :END2 #:PREFIX-LENGTH-5343))
(SUBSEQ #:STRING-5340 #:PREFIX-LENGTH-5343 #:STRING-LENGTH-5341))))
ध्यान दें कि चर #:PREFIX-LENGTH-5343
FOO
कीगणना लंबाई, चर #:PREFIX-5342
करने के लिए यहाँ बाध्य करने के लिए बाध्य किया जाता है:
यहाँ प्रपत्र (after-prefix foo bar)
के लिए विस्तार है।
अब प्रपत्र (after-prefix "foo" bar)
, जहां उपसर्ग अब एक स्ट्रिंग शाब्दिक है के लिए विस्तार को देखो:
(LET* ((#:STRING-5463 BAR) (#:STRING-LENGTH-5464 (LENGTH #:STRING-5463)))
(WHEN (AND (>= #:STRING-LENGTH-5464 3) (STRING-EQUAL "foo" #:STRING-5463 :END2 3))
(SUBSEQ #:STRING-5463 3 #:STRING-LENGTH-5464)))
अब वहाँ कोई कंप्यूटिंग "foo" की लंबाई है; यह 3.
यह इस उदाहरण में बहुत अधिक काम की तरह प्रतीत हो सकता है, लेकिन ऐसी चीजों को करने में सक्षम होने के लिए एक अच्छी शक्ति है, जैसा कि आपका प्रश्न प्रदर्शित होता है।
कई सी और सी ++ कंपाइलर्स अप्रयुक्त कोड को हटा देंगे यदि 'if' में अभिव्यक्ति संकलन समय पर निर्धारित की जा सकती है। सुनिश्चित नहीं है कि यह आपके प्रश्न का पूरी तरह उत्तर देता है। –
नहीं - उपर्युक्त उदाहरण संकलित नहीं होगा क्योंकि स्थैतिक के कुछ ब्लॉक में कोड मान्य नहीं होगा। जैसे यदि टी टाइप int int थे, तो मान .__ repr __() एक संकलित त्रुटि होगी। – Grumdrig
आपको उपरोक्त के लिए संकलित करने के लिए "स्थैतिक अगर (है (टाइप (मूल्य .__ repr__)))" को स्थिर करने की आवश्यकता है। या "स्थैतिक अगर (__ लक्षण (संकलन, मूल्य .__ repr__))"। – Baxissimo