हिस्टो द्वारा उत्कृष्ट टिप्पणियों को सारांशित करने के लिए, सामान्य तंत्र को "टेल कॉल ऑप्टिमाइज़ेशन" (टीसीओ) कहा जाता है और यह सुनिश्चित करता है कि अगर अंतिम कार्य किसी अन्य कार्य (या स्वयं) का आह्वान होता है, तो वहां नहीं होगा ढेर धक्का हो। इसके बजाय, एक साधारण कूद होगा।
एक पूंछ कॉल है क्या करने के लिए के रूप में कुछ सूक्ष्म बारीकियों रहे हैं। आइए कुछ उदाहरण देखें। सबसे सरल एक है:
def foo do
# ...
bar(...) # tail call -> nothing is pushed to the stack
end
TCO भी सशर्त भाव के लिए लागू होंगे:
def foo do
# ...
if (...) do
# ...
bar(...) # tail call
else
# ...
baz(...) # tail call
end
end
यह काम करता है क्योंकि फिर से आखिरी बात एक समारोह करता है एक समारोह की एक मंगलाचरण है। if
का परिणाम या तो bar
या baz
का परिणाम इतना ढेर पर कुछ भी पुश करने के लिए कोई जरूरत नहीं है।
इसके विपरीत, फोन करने वाले समारोह एक और कार्यप्रणाली को कॉल करने के बाद कुछ है, तो यह नहीं एक पूंछ कॉल है, और TCO नहीं होगा:
def foo do
# ...
# Not a tail call since we're doing something after bar returns
# (increment the result by 1)
1 + bar(...)
end
TCO try
में समारोह बुला रहा है को तोड़ने का एक और उदाहरण:
def foo do
try do
bar(...) # not a tail call
rescue
# ...
end
end
यह भी उल्लेख है कि TCO की वजह से आप स्टैक ट्रेस में कुछ कार्यों को नहीं देखेंगे जब एक अपवाद तब होता है लायक है:
def foo do
# ...
bar(...) # at this point foo "disappears" from stack trace
end
def bar(...) do
# ...
raise("error")
end
इस त्रुटि के ढेर डंप में foo
शामिल नहीं होगा क्योंकि यह अब ढेर पर नहीं है (इसे प्रभावी रूप से bar
के साथ बदल दिया गया है)।
दूसरा कैसे आप जुड़े हैं से
: _ "अमृत/Erlang में, इस तरह प्रत्यावर्तन एक ढेर अतिप्रवाह कारण नहीं है, क्योंकि दोनों भाषाओं तथाकथित की विशेष हैंडलिंग है" पूंछ कॉल "जो होगा, पर एक बाइट कोड स्तर, एक कूद/गोटो निर्देशों में परिवर्तित हो जाएं। परिणामस्वरूप, यह कोड बस एक अंतहीन पाश चलाता है। "_ –
धन्यवाद। मैं इस प्रश्न को उपयोगी रखने के लिए अपने शब्द को स्पष्ट कर दूंगा। –
ध्यान दें कि सामान्य रूप से रिकर्सन के लिए यह सच नहीं है, लेकिन केवल पूंछ रिकर्सन के मामले में। पूंछ प्रत्यावर्तन का मतलब है (यानी प्रत्यावर्तन समारोह की पूंछ पर होता है) है कि वर्तमान स्तर पर से कोई कोड पुनरावर्ती कॉल के बाद क्रियान्वित किया जाता है, इसलिए वर्तमान स्तर के ढेर अंतरिक्ष बनाए रखने के लिए कोई जरूरत नहीं है और इसे सुरक्षित रूप से पुन: उपयोग किया जा सकता है नेस्टेड कॉल के लिए। फ़ंक्शन कॉल करने की कोई आवश्यकता नहीं है - फ़ंक्शन बॉडी की शुरुआत में कूद पर्याप्त होगा। यह भी है कि पूंछ रिकर्सन को एफ # और संभवतः अन्य भाषाओं में अनुकूलित किया गया है। –