पूंछ स्थिति एक स्थिति है जो एक अभिव्यक्ति से कोई मान होता है। पूंछ की स्थिति में फॉर्म के मूल्यांकन के बाद मूल्यांकन किए जाने वाले कोई और रूप नहीं हैं।
से The Joy of Clojure
(defn absolute-value [x]
(if (pos? x)
x ; "then" clause
(- x))) ; "else" clause
यह एक एकल पैरामीटर और नाम यह x लेता है इस उदाहरण पर विचार। यदि एक्स पहले से ही एक सकारात्मक संख्या है, तो एक्स लौटा है; अन्यथा एक्स के विपरीत वापस आ गया है। यदि फॉर्म फ़ंक्शन की पूंछ स्थिति में है क्योंकि जो कुछ भी लौटाता है, तो पूरे फ़ंक्शन वापस आ जाएगा। "तब" खंड में एक्स फ़ंक्शन की पूंछ स्थिति में भी है। लेकिन "अन्य" खंड में एक्स फ़ंक्शन की पूंछ स्थिति में नहीं है क्योंकि x का मान फ़ंक्शन पर पास किया गया है, सीधे वापस नहीं किया गया है। एक और खंड (- x) के रूप में अन्य खंड पूंछ की स्थिति में है। क्योंकि उनमें से या तो अगर बयान से लौटाया जा सकता है
अभिव्यक्ति
(if a
b
c)
दोनों b
और c
में
इसी तरह, पूंछ की स्थिति में हैं।
अब आप अपने उदाहरण
(loop [x 5
result []]
(if (> x 0)
(recur (dec x) (conj result (+ 2 x)))
result)))
(if ...)
रूप (loop ...)
फार्म और दोनों (recur ...)
फार्म और result
प्रपत्र की पूंछ स्थिति में है में (if ...)
प्रपत्र की पूंछ स्थिति में हैं। क्योंकि (+ 1 ...)
(recur tail)
के बाद मूल्यांकन किया जाएगा
प्रश्न में दूसरी ओर है कि आप लिंक किए गए
(fn [coll] (let [tail (rest coll)]
(if (empty tail)
1
(+ 1 (recur tail)))))
recur
पर पूंछ की स्थिति में नहीं है। इसलिए क्लोजर कंपाइलर एक त्रुटि देता है।
पूंछ की स्थिति महत्वपूर्ण है क्योंकि आप पूंछ की स्थिति से recur
रूप का उपयोग कर सकते हैं। कार्यात्मक प्रोग्रामिंग भाषा आमतौर पर लूप द्वारा प्रक्रियात्मक प्रोग्रामिंग भाषाओं को पूरा करने के लिए रिकर्सन का उपयोग करती है। लेकिन रिकर्सन समस्याग्रस्त है, क्योंकि यह स्टैक स्पेस का उपभोग करता है और गहरी रिकर्सन स्टैक ओवरफ्लो समस्याओं (धीमी होने के अतिरिक्त) का कारण बन सकता है। यह समस्या आमतौर पर पूंछ कॉल अनुकूलन (टीसीओ) द्वारा हल की जाती है, जो कॉलर से दूर होती है जब रिकर्सिव कॉल किसी फ़ंक्शन/फ़ॉर्म की पूंछ स्थिति में होती है।
क्योंकि क्लोजर JVM पर होस्ट किया गया है और JVM पूंछ कॉल अनुकूलन का समर्थन नहीं करता है, इसे रिकर्सन करने के लिए एक चाल की आवश्यकता है। recur
फॉर्म वह चाल है, यह क्लोजर कंपाइलर को पूंछ कॉल अनुकूलन के समान कुछ करने की अनुमति देता है। इसके अलावा, यह सत्यापित करता है कि recur
वास्तव में पूंछ की स्थिति में है। लाभ यह है कि आप यह सुनिश्चित कर सकते हैं कि अनुकूलन वास्तव में होता है।
धन्यवाद, महान विवरण, मेरे भ्रम की स्थिति यह थी कि मैं अंतिम के मामले में एस-अभिव्यक्ति में एक पद के रूप में पूंछ स्थिति के बारे में सोच रहा था बल्कि उसके बाद मूल्यांकन। आपके स्पष्टीकरण के प्रकाश में ऐसा लगता है कि एक लूप में एकाधिक पुनरावर्ती रूपों का उपयोग करना संभव है (उदाहरण के लिए अंतिम IF s-exp की दोनों शाखाओं में) सही है? – tjb
हां यह पूरी तरह से संभव है। मुझे भी इस बात से बहुत भ्रमित होना याद है। इसके अलावा मैंने यह पढ़ना जारी रखा कि जेवीएम पर टीसीओ की कमी के कारण पुनरावृत्ति कितनी महत्वपूर्ण थी ... मुझे इनमें से किसी के बारे में पहली बात समझ नहीं आई थी (उदाहरण के लिए टीसीओ क्या है ...) और मेरा सिर था कताई ... – Paul
हाँ, यह काफी उलझन में है, और मैंने इसे कहीं भी समझाया कोई भी दस्तावेज कभी नहीं देखा। हो सकता है कि मैं सुझाव दूंगा कि वे आपके उत्तर के आधार पर पुनरावृत्ति दस्तावेज में कुछ जोड़ते हैं। – tjb