common-lisp
समूह बनाना
खोज…
समूह की आवश्यकता कब है?
आम लिस्प में कुछ स्थानों पर, क्रम में रूपों की एक श्रृंखला का मूल्यांकन किया जाता है। उदाहरण के लिए, एक डिफॉन या लैम्ब्डा के शरीर में, या एक dotimes का शरीर। उन मामलों में, क्रम में कई रूपों को लिखना उम्मीद के मुताबिक काम करता है। हालाँकि, कुछ स्थानों में, जैसे कि तत्कालीन और कुछ हिस्सों में अगर कोई भाव, केवल एक ही रूप की अनुमति है। बेशक, कोई उन स्थानों पर वास्तव में कई भावों का मूल्यांकन करना चाहता हो सकता है। उन स्थितियों के लिए, किसी प्रकार के स्पष्ट समूहन के निहितार्थ की आवश्यकता होती है।
Progn
सामान्य उद्देश्य विशेष ऑपरेटर प्रोग्न का उपयोग शून्य या अधिक रूपों के मूल्यांकन के लिए किया जाता है। अंतिम फॉर्म का मान लौटाया जाता है। उदाहरण के लिए, निम्नलिखित में, (प्रिंट 'हैलो) का मूल्यांकन किया जाता है (और इसके परिणाम की अनदेखी की जाती है), और फिर 42 का मूल्यांकन किया जाता है और उसका परिणाम ( 42 ) वापस किया जाता है:
(progn
(print 'hello)
42)
;=> 42
यदि प्रागण के भीतर कोई रूप नहीं हैं, तो शून्य वापस आ गया है:
(progn)
;=> NIL
रूपों की एक श्रृंखला को समूहीकृत करने के अलावा, प्रोग्न में यह महत्वपूर्ण गुण भी है कि यदि प्रोग्नम फॉर्म एक शीर्ष-स्तरीय रूप है , तो इसके भीतर के सभी रूपों को शीर्ष स्तर के रूपों के रूप में संसाधित किया जाता है। मैक्रोज़ लिखते समय यह महत्वपूर्ण हो सकता है जो कई रूपों में विस्तारित होता है जिन्हें सभी को शीर्ष स्तर के रूपों के रूप में संसाधित किया जाना चाहिए।
प्रज्ञा इस मायने में भी मूल्यवान है कि वह अंतिम रूप के सभी मूल्यों को लौटाती है। उदाहरण के लिए,
(progn
(print 'hello)
(values 1 2 3))
;;=> 1, 2, 3
इसके विपरीत, कुछ समूहीकरण अभिव्यक्तियाँ केवल परिणाम-उत्पादक रूप का प्राथमिक मान लौटाती हैं।
निष्प्राण सिद्धियाँ
कुछ रूप उनके व्यवहार का वर्णन करने के लिए निहितार्थ का उपयोग करते हैं। उदाहरण के लिए, जब और जब तक कि मैक्रोज़, जो अनिवार्य रूप से एक तरफा हैं, यदि फॉर्म में निहित व्यवहार के संदर्भ में उनके व्यवहार का वर्णन करते हैं। इसका मतलब है कि एक रूप जैसा
(when (foo-p foo)
form1
form2)
मूल्यांकन किया जाता है और हालत (foo-पी foo) सत्य है, तभी Form1 और Form2 बांटा जाता है जैसे कि वे एक progn के भीतर समाहित कर रहे थे। जब स्थूल का विस्तार अनिवार्य रूप से होता है:
(if (foo-p foo)
(progn
form1
form2)
nil)
प्रोग 1 और प्रोग 2
अक्सर बार, यह कई भावों का मूल्यांकन करने और अंतिम के बजाय पहले या दूसरे रूप से परिणाम वापस करने में सहायक होता है। उदाहरण के लिए, लेट और का उपयोग करके इसे पूरा करना आसान है:
(let ((form1-result form1))
form2
form3
;; ...
form-n-1
form-n
form1-result)
क्योंकि यह फ़ॉर्म कुछ अनुप्रयोगों में सामान्य है, कॉमन लिस्प में prog1 और prog2 शामिल हैं जो प्रोग्नम की तरह हैं, लेकिन क्रमशः पहले और दूसरे रूपों के परिणाम वापस करते हैं। उदाहरण के लिए:
(prog1
42
(print 'hello)
(print 'goodbye))
;; => 42
(prog2
(print 'hello)
42
(print 'goodbye))
;; => 42
Prog1 / prog2 और progn बीच एक महत्वपूर्ण अंतर यह है कि progn रिटर्न पिछले प्रपत्र के सभी मानों, जबकि prog1 और prog2 केवल पहले और दूसरे रूप के प्राथमिक मान है। उदाहरण के लिए:
(progn
(print 'hello)
(values 1 2 3))
;;=> 1, 2, 3
(prog1
(values 1 2 3)
(print 'hello))
;;=> 1 ; not 1, 2, 3
Prog1 शैली मूल्यांकन के साथ कई मानों के लिए, इसके बजाय कई-मान-prog1 का उपयोग करें। कोई समान बहु-मूल्य-प्रोग 2 नहीं है , लेकिन यदि आपको इसकी आवश्यकता है तो इसे लागू करना मुश्किल नहीं है।
खंड मैथा
विशेष ऑपरेटर ब्लॉक कई लिस्प रूपों (जैसे एक progn
संकेत) के समूहीकरण की अनुमति देता है और यह ब्लॉक का नाम रखने के लिए एक नाम भी लेता है। जब ब्लॉक के भीतर के रूपों का मूल्यांकन किया जाता है, तो विशेष ऑपरेटर रिटर्न- ब्लॉक का उपयोग ब्लॉक छोड़ने के लिए किया जा सकता है। उदाहरण के लिए:
(block foo
(print 'hello) ; evaluated
(return-from foo)
(print 'goodbye)) ; not evaluated
;;=> NIL
रिटर्न-से भी रिटर्न वैल्यू प्रदान की जा सकती है:
(block foo
(print 'hello) ; evaluated
(return-from foo 42)
(print 'goodbye)) ; not evaluated
;;=> 42
नामांकित ब्लॉक उपयोगी होते हैं जब कोड का एक हिस्सा एक सार्थक नाम होता है, या जब ब्लॉक नेस्टेड होते हैं। कुछ संदर्भ में, केवल एक ब्लॉक से जल्दी लौटने की क्षमता महत्वपूर्ण है। उस स्थिति में, आप ब्लॉक नाम के रूप में नील का उपयोग कर सकते हैं, और वापस लौट सकते हैं । रिटर्न सिर्फ रिटर्न से ही है , सिवाय इसके कि ब्लॉक का नाम हमेशा शून्य होता है ।
नोट: संलग्न प्रपत्र शीर्ष-स्तरीय रूप नहीं हैं। यह progn
से अलग है, जहां एक शीर्ष-स्तरीय progn
फॉर्म के संलग्न रूपों को अभी भी शीर्ष-स्तरीय रूप माना जाता है।
Tagbody
एक समूह रूपों में बहुत सारे नियंत्रण के लिए, टैगबॉडी विशेष ऑपरेटर बहुत मददगार हो सकता है। टैगबॉडी फॉर्म के अंदर के फॉर्म या तो गो टैग होते हैं (जो सिर्फ प्रतीक या पूर्णांक होते हैं) या निष्पादित करने के लिए फॉर्म। एक टैगबॉडी के भीतर, गो विशेष ऑपरेटर का उपयोग निष्पादन को एक नए स्थान पर स्थानांतरित करने के लिए किया जाता है। इस प्रकार की प्रोग्रामिंग को काफी निम्न स्तर का माना जा सकता है, क्योंकि यह मनमाने ढंग से निष्पादन पथ की अनुमति देता है। निम्नलिखित क्या एक के लिए लूप जब एक tagbody के रूप में लागू की तरह लग रहे हो सकता है की एक वर्बोज़ उदाहरण है:
(let (x) ; for (x = 0; x < 5; x++) { print(hello); }
(tagbody
(setq x 0)
prologue
(unless (< x 5)
(go end))
begin
(print (list 'hello x))
epilogue
(incf x)
(go prologue)
end))
जबकि टैगबॉडी और गो आमतौर पर उपयोग नहीं किए जाते हैं, शायद " जीओटीओ हानिकारक माना जाता है" के कारण, लेकिन राज्य मशीनों के लिए जटिल नियंत्रण संरचनाओं को लागू करते समय मददगार हो सकता है। कई पुनरावृत्ति निर्माण एक अंतर्निहित टैगबॉडी में भी विस्तार करते हैं। उदाहरण के लिए, टोटकों की एक श्रृंखला टैग और रूपों के रूप में निर्दिष्ट की जाती है।
किस फॉर्म का इस्तेमाल करना है?
जब मैक्रोज़ लिखते हैं जो उन रूपों में विस्तारित होते हैं जिनमें समूहीकरण शामिल हो सकता है, तो यह विचार करने के लिए कि किस समूहीकरण निर्माण पर विचार करना कुछ समय बिताना सार्थक है।
उदाहरण के लिए, परिभाषा शैली रूपों के लिए, एक परिभाषित-विजेट मैक्रो, जो आमतौर पर एक शीर्ष-स्तरीय रूप के रूप में दिखाई देगा, और यह कि कई डिफ्यून्स एस, डिस्ट्रक्ट एस आदि, यह आमतौर पर एक प्रागण का उपयोग करने के लिए समझ में आता है, ताकि बच्चे के रूप हैं शीर्ष-स्तरीय रूपों के रूप में संसाधित। पुनरावृत्ति रूपों के लिए, एक अंतर्निहित टैग अधिक सामान्य है।
उदाहरण के लिए, के शरीर dotimes , dolist , और ऐसा प्रत्येक एक अंतर्निहित tagbody में विस्तार।
कोड के नाम "चंक" को परिभाषित करने वाले रूपों के लिए, एक निहित ब्लॉक अक्सर उपयोगी होता है। उदाहरण के लिए, जबकि एक डिफॉन का शरीर एक अंतर्निहित प्रग्न के अंदर होता है , जिसका अर्थ है कि प्रोग्नेंट फ़ंक्शन के नाम को साझा करने वाले ब्लॉक के भीतर है। इसका मतलब है कि रिटर्न- फंक्शन का उपयोग फ़ंक्शन से बाहर निकलने के लिए किया जा सकता है। इस तरह के एक COMP