अनाम पुनरावर्तन: Difference between revisions

From Vigyanwiki
No edit summary
No edit summary
 
(5 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{short description|Recursion without calling a function by name}}
{{short description|Recursion without calling a function by name}}
[[कंप्यूटर विज्ञान]] में, अनाम रिकर्सन [[रिकर्सन (कंप्यूटर विज्ञान)]] है जो स्पष्ट रूप से किसी फ़ंक्शन को नाम से नहीं बुलाता है। यह या तो स्पष्ट रूप से, उच्च-क्रम वाले फ़ंक्शन का उपयोग करके किया जा सकता है - किसी फ़ंक्शन को तर्क के रूप में पारित करना और उसे कॉल करना - या परोक्ष रूप से, [[प्रतिबिंब (कंप्यूटर प्रोग्रामिंग)]] सुविधाओं के माध्यम से जो किसी को वर्तमान संदर्भ, विशेष रूप से वर्तमान फ़ंक्शन या कभी-कभी वर्तमान फ़ंक्शन के कॉलिंग फ़ंक्शन के आधार पर कुछ कार्यों तक पहुंचने की अनुमति देता है।
[[कंप्यूटर विज्ञान]] में, '''एनोनिमस रिकर्सन''' [[रिकर्सन (कंप्यूटर विज्ञान)]] है जो स्पष्ट रूप से किसी फ़ंक्शन को नाम से नहीं बुलाता है। यह या तो स्पष्ट रूप से, उच्च-क्रम वाले फ़ंक्शन का उपयोग करके किया जा सकता है - किसी फ़ंक्शन को लॉजिक के रूप में सिद्ध करना और उसे कॉल करना या परोक्ष रूप से, [[प्रतिबिंब (कंप्यूटर प्रोग्रामिंग)|रिफ्लेक्शन (कंप्यूटर प्रोग्रामिंग)]] सुविधाओं के माध्यम से जो किसी को वर्तमान संदर्भ, विशेष रूप से वर्तमान फ़ंक्शन या कभी-कभी वर्तमान फ़ंक्शन के कॉलिंग फ़ंक्शन के आधार पर कुछ कार्यों तक पहुंचने की अनुमति देता है।


प्रोग्रामिंग अभ्यास में, [[जावास्क्रिप्ट]] में अनाम रिकर्सन का विशेष रूप से उपयोग किया जाता है, जो इसका समर्थन करने के लिए प्रतिबिंब सुविधाएं प्रदान करता है। हालाँकि, सामान्य प्रोग्रामिंग अभ्यास में, इसे खराब शैली माना जाता है, और इसके बजाय नामित कार्यों के साथ रिकर्सन का सुझाव दिया जाता है। कार्यों को तर्कों के रूप में स्पष्ट रूप से पारित करने के माध्यम से अज्ञात पुनरावृत्ति किसी भी भाषा में संभव है जो तर्कों के रूप में कार्यों का समर्थन करती है, हालांकि व्यवहार में इसका उपयोग शायद ही कभी किया जाता है, क्योंकि यह नाम से स्पष्ट रूप से पुनरावृत्ति की तुलना में अधिक लंबा और कम स्पष्ट है।
प्रोग्रामिंग अभ्यास में, [[जावास्क्रिप्ट]] में एनोनिमस रिकर्सन का विशेष रूप से उपयोग किया जाता है, जो इसका समर्थन करने के लिए रिफ्लेक्शन सुविधाएं प्रदान करता है। चूँकि, सामान्य प्रोग्रामिंग अभ्यास में, इसे व्यर्थ शैली माना जाता है, और इसके अतिरिक्त नामांकित कार्यों के साथ रिकर्सन का सुझाव दिया जाता है। इस प्रकार कार्यों को लॉजिक के रूप में स्पष्ट रूप से सिद्ध करने के माध्यम से एनोनिमस रिकर्सन किसी भी लैंग्वेज में संभव है जो लॉजिक के रूप में कार्यों का समर्थन करती है, चूँकि व्यवहार में इसका उपयोग संभवतः ही कभी किया जाता है, क्योंकि यह नाम से स्पष्ट रूप से रिकर्सन की तुलना में अधिक लंबा और कम स्पष्ट है।


सैद्धांतिक कंप्यूटर विज्ञान में, अनाम रिकर्सन महत्वपूर्ण है, क्योंकि यह दर्शाता है कि कोई नामित कार्यों की आवश्यकता के बिना रिकर्सन लागू कर सकता है। यह [[लैम्ब्डा कैलकुलस]] के लिए विशेष रूप से महत्वपूर्ण है, जिसमें अनाम यूनरी फ़ंक्शन हैं, लेकिन किसी भी पुनरावर्ती फ़ंक्शन की गणना करने में सक्षम है। इस अनाम रिकर्सन को निश्चित-बिंदु कॉम्बिनेटर के माध्यम से सामान्य रूप से उत्पादित किया जा सकता है।
सैद्धांतिक कंप्यूटर विज्ञान में, एनोनिमस रिकर्सन महत्वपूर्ण है, क्योंकि यह दर्शाता है कि कोई नामांकित कार्यों की आवश्यकता के बिना रिकर्सन प्रयुक्त कर सकता है। यह [[लैम्ब्डा कैलकुलस]] के लिए विशेष रूप से महत्वपूर्ण है, जिसमें एनोनिमस यूनरी फ़ंक्शन हैं, किन्तु किसी भी पुनरावर्ती फ़ंक्शन की गणना करने में सक्षम है। इस एनोनिमस रिकर्सन को निश्चित-बिंदु कॉम्बिनेटर के माध्यम से सामान्य रूप से उत्पादित किया जा सकता है।


==उपयोग==
==उपयोग==
अनाम रिकर्सन का उपयोग मुख्य रूप से अज्ञात कार्यों के लिए रिकर्सन की अनुमति देने में किया जाता है, खासकर जब वे क्लोजर (कंप्यूटर विज्ञान) बनाते हैं या फ़ंक्शन के [[नाम बंधन]] से बचने के लिए [[कॉलबैक (कंप्यूटर प्रोग्रामिंग)]] के रूप में उपयोग किए जाते हैं।
एनोनिमस रिकर्सन का उपयोग मुख्य रूप से एनोनिमस कार्यों के लिए रिकर्सन की अनुमति देने में किया जाता है, विशेष रूप से जब वह क्लोजर (कंप्यूटर विज्ञान) बनाते हैं या फ़ंक्शन के [[नाम बंधन|क्लोज़र]] से बचने के लिए [[कॉलबैक (कंप्यूटर प्रोग्रामिंग)]] के रूप में उपयोग किए जाते हैं।


अनाम रिकर्सन में मुख्य रूप से वर्तमान फ़ंक्शन को कॉल करना शामिल है, जिसके परिणामस्वरूप प्रत्यक्ष रिकर्सन होता है। अनाम अप्रत्यक्ष रिकर्सन संभव है, जैसे कि कॉलर (पिछले फ़ंक्शन) को कॉल करके, या, शायद ही कभी, [[कॉल स्टैक]] में और ऊपर जाकर, और इसे पारस्परिक रिकर्सन उत्पन्न करने के लिए श्रृंखलाबद्ध किया जा सकता है। वर्तमान फ़ंक्शन का स्व-संदर्भ [[ ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग |ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग]] में इस (कंप्यूटर प्रोग्रामिंग) कीवर्ड का कार्यात्मक समकक्ष है, जो किसी को वर्तमान संदर्भ को संदर्भित करने की अनुमति देता है।
एनोनिमस रिकर्सन में मुख्य रूप से वर्तमान फ़ंक्शन को कॉल करना सम्मिलित है, जिसके परिणामस्वरूप प्रत्यक्ष रिकर्सन होता है। एनोनिमस अप्रत्यक्ष रिकर्सन संभव है, जैसे कि कॉलर (पिछले फ़ंक्शन) को कॉल करके, या, संभवतः ही कभी, [[कॉल स्टैक]] में और ऊपर जाकर, और इसे पारस्परिक रिकर्सन उत्पन्न करने के लिए श्रृंखलाबद्ध किया जा सकता है। वर्तमान फ़ंक्शन का स्व-संदर्भ [[ ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग |ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग]] में इस (कंप्यूटर प्रोग्रामिंग) कीवर्ड का कार्यात्मक समकक्ष है, जो किसी को वर्तमान संदर्भ को संदर्भित करने की अनुमति देता है।


अनाम रिकर्सन का उपयोग नामित फ़ंक्शंस के लिए भी किया जा सकता है, बल्कि उन्हें नाम से कॉल करना, यह निर्दिष्ट करना कि कोई वर्तमान फ़ंक्शन पर रिकर्सन कर रहा है, या किसी को उस नाम को बदलने की आवश्यकता के बिना फ़ंक्शन का नाम बदलने की अनुमति देना जहां यह स्वयं कॉल करता है। हालाँकि, [[प्रोग्रामिंग शैली]] के मामले में यह आम तौर पर नहीं किया जाता है।
एनोनिमस रिकर्सन का उपयोग नामांकित फ़ंक्शंस के लिए भी किया जा सकता है, किन्तु उन्हें नाम से कॉल करना होता है, यह निर्दिष्ट करना कि कोई वर्तमान फ़ंक्शन पर रिकर्सन कर रहा है, या किसी को उस नाम को परिवर्तन करने की आवश्यकता के बिना फ़ंक्शन का नाम परिवर्तन करने की अनुमति देना जहां यह स्वयं कॉल करता है। चूँकि, [[प्रोग्रामिंग शैली]] के स्थिति में यह सामान्यतः नहीं किया जाता है।


==विकल्प==
==विकल्प==


===नामित फ़ंक्शन===
===नामांकित फ़ंक्शन===
सामान्य विकल्प नामित फ़ंक्शंस और नामित रिकर्सन का उपयोग करना है। अनाम फ़ंक्शन को देखते हुए, यह या तो फ़ंक्शन में नाम बाइंड करके किया जा सकता है, जैसा कि जावास्क्रिप्ट में नामित फ़ंक्शन एक्सप्रेशन में होता है, या फ़ंक्शन को वेरिएबल में निर्दिष्ट करके और फिर वेरिएबल को कॉल करके किया जा सकता है, जैसा कि जावास्क्रिप्ट में फ़ंक्शन स्टेटमेंट में होता है। चूँकि जो भाषाएँ अनाम फ़ंक्शंस की अनुमति देती हैं, वे आम तौर पर इन फ़ंक्शंस को वेरिएबल्स (यदि प्रथम श्रेणी फ़ंक्शंस नहीं) को निर्दिष्ट करने की अनुमति देती हैं, तो कई भाषाएँ स्वयं फ़ंक्शन को संदर्भित करने का कोई तरीका प्रदान नहीं करती हैं, और स्पष्ट रूप से अनाम रिकर्सन को अस्वीकार करती हैं; उदाहरणों में गो (प्रोग्रामिंग भाषा) शामिल है।<ref>[https://code.google.com/p/go/issues/detail?id=226 Issue 226: It's impossible to recurse a anonymous function in Go without workarounds.]</ref>
सामान्य विकल्प नामांकित फ़ंक्शंस और नामांकित रिकर्सन का उपयोग करना है। एनोनिमस फ़ंक्शन को देखते हुए, यह या तो फ़ंक्शन में नाम बाइंड करके किया जा सकता है, जैसा कि जावास्क्रिप्ट में नामांकित फ़ंक्शन एक्सप्रेशन में होता है, या फ़ंक्शन को वेरिएबल में निर्दिष्ट करके और फिर वेरिएबल को कॉल करके किया जा सकता है, जैसा कि जावास्क्रिप्ट में फ़ंक्शन स्टेटमेंट में होता है। चूँकि जो लैंग्वेजएँ एनोनिमस फ़ंक्शंस की अनुमति देती हैं, वह सामान्यतः इन फ़ंक्शंस को वेरिएबल्स (यदि प्रथम श्रेणी फ़ंक्शंस नहीं) को निर्दिष्ट करने की अनुमति देती हैं, तो अनेक लैंग्वेजएँ स्वयं फ़ंक्शन को संदर्भित करने का कोई विधि प्रदान नहीं करती हैं, और स्पष्ट रूप से एनोनिमस रिकर्सन को अस्वीकार करती हैं; उदाहरणों में गो (प्रोग्रामिंग लैंग्वेज) सम्मिलित है।<ref>[https://code.google.com/p/go/issues/detail?id=226 Issue 226: It's impossible to recurse a anonymous function in Go without workarounds.]</ref>
उदाहरण के लिए, जावास्क्रिप्ट में फैक्टोरियल फ़ंक्शन को अज्ञात रिकर्सन के माध्यम से परिभाषित किया जा सकता है:<ref name=olliej>[https://stackoverflow.com/a/235760 answer] by olliej, Oct 25 '08 to "[https://stackoverflow.com/q/103598 Why was the arguments.callee.caller property deprecated in JavaScript?]", ''StackOverflow''</ref>
 
उदाहरण के लिए, जावास्क्रिप्ट में फैक्टोरियल फ़ंक्शन को एनोनिमस रिकर्सन के माध्यम से परिभाषित किया जा सकता है:<ref name="olliej">[https://stackoverflow.com/a/235760 answer] by olliej, Oct 25 '08 to "[https://stackoverflow.com/q/103598 Why was the arguments.callee.caller property deprecated in JavaScript?]", ''StackOverflow''</ref>
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
[1, 2, 3, 4, 5].map(function(n) {
[1, 2, 3, 4, 5].map(function(n) {
Line 23: Line 24:
});
});
</syntaxhighlight>
</syntaxhighlight>
नामित फ़ंक्शन अभिव्यक्ति का उपयोग करने के लिए पुनः लिखे जाने पर यह प्राप्त होता है:
नामांकित फ़ंक्शन अभिव्यक्ति का उपयोग करने के लिए पुनः लिखे जाने पर यह प्राप्त होता है:
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
[1, 2, 3, 4, 5].map(function factorial(n) {
[1, 2, 3, 4, 5].map(function factorial(n) {
Line 30: Line 31:
</syntaxhighlight>
</syntaxhighlight>


 
===फ़ंक्शंस को लॉजिक के रूप में पास करना===
===फ़ंक्शंस को तर्क के रूप में पास करना===
वर्तमान फ़ंक्शन या कॉलिंग फ़ंक्शन को संदर्भित करने के लिए तंत्र के बिना भी, ऐसी लैंग्वेज में एनोनिमस रिकर्सन संभव है जो फ़ंक्शन को लॉजिक के रूप में अनुमति देता है। यह मूल पुनरावर्ती फ़ंक्शन में और मापदंड जोड़कर और पुनरावर्ती कॉल के लिए फ़ंक्शन के रूप में इस मापदंड का उपयोग करके किया जाता है। यह उच्च-क्रम फ़ंक्शन बनाता है, और इस उच्च फ़ंक्शन को पास करने से वास्तविक पुनरावर्ती फ़ंक्शन के अन्दर एनोनिमस रिकर्सन की अनुमति मिलती है। इस उच्च क्रम फ़ंक्शन पर निश्चित-बिंदु कॉम्बिनेटर प्रयुक्त करके इसे पूरी तरह से गुमनाम रूप से किया जा सकता है। यह मुख्य रूप से अकादमिक रुचि का है, विशेष रूप से यह दिखाने के लिए कि लैम्ब्डा कैलकुलस में रिकर्सन है, क्योंकि परिणामी अभिव्यक्ति मूल नामांकित रिकर्सिव फ़ंक्शन की तुलना में अधिक सम्मिश्र है। इसके विपरीत, फिक्स्ड-पॉइंटेड कॉम्बिनेटर्स के उपयोग को सामान्य रूप से एनोनिमस रिकर्सन के रूप में संदर्भित किया जा सकता है, क्योंकि यह उनका उल्लेखनीय उपयोग है, चूँकि उनके पास अन्य अनुप्रयोग हैं।<ref>This terminology appear to be largely [[mathematical folklore|folklore]], but it does appear in the following:
वर्तमान फ़ंक्शन या कॉलिंग फ़ंक्शन को संदर्भित करने के लिए तंत्र के बिना भी, ऐसी भाषा में अज्ञात रिकर्सन संभव है जो फ़ंक्शन को तर्क के रूप में अनुमति देता है। यह मूल पुनरावर्ती फ़ंक्शन में और पैरामीटर जोड़कर और पुनरावर्ती कॉल के लिए फ़ंक्शन के रूप में इस पैरामीटर का उपयोग करके किया जाता है। यह उच्च-क्रम फ़ंक्शन बनाता है, और इस उच्च फ़ंक्शन को पास करने से वास्तविक पुनरावर्ती फ़ंक्शन के भीतर अज्ञात रिकर्सन की अनुमति मिलती है। इस उच्च क्रम फ़ंक्शन पर निश्चित-बिंदु कॉम्बिनेटर लागू करके इसे पूरी तरह से गुमनाम रूप से किया जा सकता है। यह मुख्य रूप से अकादमिक रुचि का है, विशेष रूप से यह दिखाने के लिए कि लैम्ब्डा कैलकुलस में रिकर्सन है, क्योंकि परिणामी अभिव्यक्ति मूल नामित रिकर्सिव फ़ंक्शन की तुलना में काफी अधिक जटिल है। इसके विपरीत, फिक्स्ड-पॉइंटेड कॉम्बिनेटर्स के उपयोग को सामान्य रूप से अज्ञात रिकर्सन के रूप में संदर्भित किया जा सकता है, क्योंकि यह उनका उल्लेखनीय उपयोग है, हालांकि उनके पास अन्य अनुप्रयोग हैं।<ref>This terminology appear to be largely [[mathematical folklore|folklore]], but it does appear in the following:
* Trey Nash, ''Accelerated C# 2008'', Apress, 2007, {{ISBN|1-59059-873-3}}, p. 462—463. Derived substantially<!--gives him credit!--> from [http://www.linkedin.com/pub/wes-dyer/2/727/a39 Wes Dyer]'s blog (see next item).
* Trey Nash, ''Accelerated C# 2008'', Apress, 2007, {{ISBN|1-59059-873-3}}, p. 462—463. Derived substantially<!--gives him credit!--> from [http://www.linkedin.com/pub/wes-dyer/2/727/a39 Wes Dyer]'s blog (see next item).
* Wes Dyer [http://blogs.msdn.com/wesdyer/archive/2007/02/02/anonymous-recursion-in-c.aspx Anonymous Recursion in C#], February 02, 2007, contains a substantially similar example found in the book above, but accompanied by more discussion.</ref><ref name=ifworks>The If Works [http://blog.jcoglan.com/2008/01/10/deriving-the-y-combinator/ Deriving the Y combinator], January 10th, 2008</ref>
* Wes Dyer [http://blogs.msdn.com/wesdyer/archive/2007/02/02/anonymous-recursion-in-c.aspx Anonymous Recursion in C#], February 02, 2007, contains a substantially similar example found in the book above, but accompanied by more discussion.</ref><ref name=ifworks>The If Works [http://blog.jcoglan.com/2008/01/10/deriving-the-y-combinator/ Deriving the Y combinator], January 10th, 2008</ref>
इसे नीचे पायथन का उपयोग करके दर्शाया गया है। सबसे पहले, रिकर्सन नामक मानक:
 
इसे नीचे पायथन फर्स्ट रिकर्सन नामक मानक का उपयोग करके चित्रित किया गया है:
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
def fact(n):
def fact(n):
Line 42: Line 43:
     return n * fact(n - 1)
     return n * fact(n - 1)
</syntaxhighlight>
</syntaxhighlight>
उच्च-क्रम फ़ंक्शन का उपयोग करना ताकि शीर्ष-स्तरीय फ़ंक्शन किसी तर्क पर गुमनाम रूप से पुनरावृत्ति कर सके, लेकिन फिर भी तर्क के रूप में मानक पुनरावर्ती फ़ंक्शन की आवश्यकता होती है:
उच्च-क्रम फ़ंक्शन का उपयोग करना जिससे टॉप-लेबल फ़ंक्शन किसी लॉजिक पर अनोनीमौसली रूप से रिकर्सन कर सकते है, किन्तु फिर भी लॉजिक के रूप में मानक पुनरावर्ती फ़ंक्शन की आवश्यकता होती है:
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
def fact0(n0):
def fact0(n0):
Line 51: Line 52:
fact = lambda n: fact1(fact0, n)
fact = lambda n: fact1(fact0, n)
</syntaxhighlight>
</syntaxhighlight>
हम फ़ंक्शन तर्क को कॉल में पास करके मानक पुनरावर्ती फ़ंक्शन को समाप्त कर सकते हैं:
हम फ़ंक्शन लॉजिक को कॉल में पास करके मानक पुनरावर्ती फ़ंक्शन को समाप्त कर सकते हैं:
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
fact1 = lambda f, n1: 1 if n1 == 0 else n1 * f(f, n1 - 1)
fact1 = lambda f, n1: 1 if n1 == 0 else n1 * f(f, n1 - 1)
fact = lambda n: fact1(fact1, n)
fact = lambda n: fact1(fact1, n)
</syntaxhighlight>
</syntaxhighlight>
दूसरी पंक्ति को सामान्य उच्च-क्रम फ़ंक्शन द्वारा प्रतिस्थापित किया जा सकता है जिसे [[संयोजनात्मक तर्क]] कहा जाता है:
दूसरी पंक्ति को सामान्य हायर-आर्डर फ़ंक्शन द्वारा प्रतिस्थापित किया जा सकता है जिसे [[संयोजनात्मक तर्क|कॉम्बिनेटर लॉजिक]] कहा जाता है:
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
F = lambda f: (lambda x: f(f, x))
F = lambda f: (lambda x: f(f, x))
Line 62: Line 63:
fact = F(fact1)
fact = F(fact1)
</syntaxhighlight>
</syntaxhighlight>
गुमनाम रूप से लिखा गया:<ref>[https://stackoverflow.com/a/8703135/2025416 Hugo Walter's answer] to "[https://stackoverflow.com/q/481692 Can a lambda function call itself recursively in Python?]"</ref>
एनोनिमस रूप से लिखा गया:<ref>[https://stackoverflow.com/a/8703135/2025416 Hugo Walter's answer] to "[https://stackoverflow.com/q/481692 Can a lambda function call itself recursively in Python?]"</ref>
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
(lambda f: (lambda x: f(f, x))) \
(lambda f: (lambda x: f(f, x))) \
(lambda g, n1: 1 if n1 == 0 else n1 * g(g, n1 - 1))
(lambda g, n1: 1 if n1 == 0 else n1 * g(g, n1 - 1))
</syntaxhighlight>
</syntaxhighlight>
लैम्ब्डा कैलकुलस में, जो केवल ही चर के कार्यों का उपयोग करता है, यह फिक्स्ड-पॉइंट कॉम्बिनेटर के माध्यम से किया जा सकता है। पहले दो वेरिएबल्स के उच्च-क्रम वाले फ़ंक्शन को एकल वेरिएबल का फ़ंक्शन बनाएं, जो [[करी]] द्वारा सीधे फ़ंक्शन लौटाता है:
लैम्ब्डा कैलकुलस में, जो केवल ही चर के कार्यों का उपयोग करता है, यह फिक्स्ड-पॉइंट कॉम्बिनेटर के माध्यम से किया जा सकता है। पहले दो वेरिएबल्स के उच्च-क्रम वाले फ़ंक्शन को एकल वेरिएबल का फ़ंक्शन बनाएं, जो [[करी|कर्र्यिंग]] द्वारा सीधे फ़ंक्शन लौटाता है:
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
fact1 = lambda f: (lambda n1: 1 if n1 == 0 else n1 * f(f)(n1 - 1))
fact1 = lambda f: (lambda n1: 1 if n1 == 0 else n1 * f(f)(n1 - 1))
fact = fact1(fact1)
fact = fact1(fact1)
</syntaxhighlight>
</syntaxhighlight>
यहां दो उच्च क्रम फ़ंक्शन को अपने आप में लागू करने वाले ऑपरेशन हैं: <code>f(f)</code> पहली पंक्ति में और <code>fact1(fact1)</code> क्षण में। कॉम्बिनेटरी लॉजिक में दूसरे दोहरे अनुप्रयोग का गुणनखंड करने से परिणाम मिलते हैं:
यहां दो हायर-आर्डर फ़ंक्शन को अपने आप में प्रयुक्त करने वाले ऑपरेशन हैं: <code>f(f)</code> पहली पंक्ति में और <code>fact1(fact1)</code> क्षण में। कॉम्बिनेटरी लॉजिक में दूसरे दोहरे अनुप्रयोग का गुणनखंड करने से परिणाम मिलते हैं:
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
C = lambda x: x(x)
C = lambda x: x(x)
Line 100: Line 101:
fact = Y(fact1)
fact = Y(fact1)
</syntaxhighlight>
</syntaxhighlight>
इनके संयोजन से लैम्ब्डा कैलकुलस (एकल चर के अज्ञात कार्य) में फैक्टोरियल की पुनरावर्ती परिभाषा प्राप्त होती है:<ref>[https://stackoverflow.com/a/10144992/2025416 Nux's answer] to "[https://stackoverflow.com/q/481692 Can a lambda function call itself recursively in Python?]"</ref>
इनके संयोजन से लैम्ब्डा कैलकुलस (एकल चर के एनोनिमस कार्य) में फैक्टोरियल की पुनरावर्ती परिलैंग्वेज प्राप्त होती है:<ref>[https://stackoverflow.com/a/10144992/2025416 Nux's answer] to "[https://stackoverflow.com/q/481692 Can a lambda function call itself recursively in Python?]"</ref>
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
(lambda f: (lambda x: f(lambda v: x(x)(v)))
(lambda f: (lambda x: f(lambda v: x(x)(v)))
Line 106: Line 107:
(lambda g: (lambda n1: 1 if n1 == 0 else n1 * g(n1 - 1)))
(lambda g: (lambda n1: 1 if n1 == 0 else n1 * g(n1 - 1)))
</syntaxhighlight>
</syntaxhighlight>
==उदाहरण==
==उदाहरण==


===एपीएल===
===एपीएल===
[[एपीएल (प्रोग्रामिंग भाषा)]] में, वर्तमान [[डीएफएनएस]] तक पहुंच योग्य है <code>∇</code>. यह अज्ञात रिकर्सन की अनुमति देता है, जैसे कि फैक्टोरियल के इस कार्यान्वयन में:
[[एपीएल (प्रोग्रामिंग भाषा)|एपीएल (प्रोग्रामिंग लैंग्वेज)]] में वर्तमान [[डीएफएनएस]] <code>∇</code> के माध्यम से पहुंच योग्य है। यह एनोनिमस रिकर्सन की अनुमति देता है, जैसे कि फैक्टोरियल के इस कार्यान्वयन में:
<syntaxhighlight lang=apl>
<syntaxhighlight lang=apl>
   {0=⍵:1 ⋄ ⍵×∇ ⍵-1} 5
   {0=⍵:1 ⋄ ⍵×∇ ⍵-1} 5
Line 118: Line 117:
1 1 2 6 24 120 720 5040 40320 362880
1 1 2 6 24 120 720 5040 40320 362880
</syntaxhighlight>
</syntaxhighlight>
===जावास्क्रिप्ट===
जावास्क्रिप्ट में, वर्तमान फ़ंक्शन <code>arguments.callee</code> के माध्यम से एक्सेस किया जा सकता है , जबकि कॉलिंग फ़ंक्शन को <code>arguments.caller</code> माध्यम से पहुंच योग्य है ये एनोनिमस रिकर्सन की अनुमति देते हैं, जैसे कि फैक्टोरियल के इस कार्यान्वयन में:<ref name=olliej />


===जावास्क्रिप्ट===
जावास्क्रिप्ट में, वर्तमान फ़ंक्शन तक पहुंच योग्य है <code>arguments.callee</code>, जबकि कॉलिंग फ़ंक्शन के माध्यम से पहुंच योग्य है <code>arguments.caller</code>. ये अज्ञात रिकर्सन की अनुमति देते हैं, जैसे कि फैक्टोरियल के इस कार्यान्वयन में:<ref name=olliej />
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
[1, 2, 3, 4, 5].map(function(n) {
[1, 2, 3, 4, 5].map(function(n) {
Line 127: Line 125:
});
});
</syntaxhighlight>
</syntaxhighlight>
===[[पर्ल]]===
===[[पर्ल]]===
पर्ल 5.16 से शुरू होकर, वर्तमान सबरूटीन इसके माध्यम से पहुंच योग्य है <code>__SUB__</code> टोकन, जो वर्तमान सबरूटीन का संदर्भ लौटाता है, या <code>undef</code> सबरूटीन के बाहर.<ref>Perldoc, "[http://perldoc.perl.org/feature.html#The-'current_sub'-feature The 'current_sub' feature]", perldoc feature</ref> यह अज्ञात रिकर्सन की अनुमति देता है, जैसे कि फैक्टोरियल के निम्नलिखित कार्यान्वयन में:
पर्ल 5.16 से प्रारंभ होकर, वर्तमान सबरूटीन <code>__SUB__</code> माध्यम से पहुंच योग्य है जो वर्तमान सबरूटीन का संदर्भ लौटाता है, या इस प्रकार<code>undef</code> सबरूटीन के बाहर.<ref>Perldoc, "[http://perldoc.perl.org/feature.html#The-'current_sub'-feature The 'current_sub' feature]", perldoc feature</ref> यह एनोनिमस रिकर्सन की अनुमति देता है, जैसे कि फैक्टोरियल के निम्नलिखित कार्यान्वयन में:
<syntaxhighlight lang="perl">
<syntaxhighlight lang="perl">
#!/usr/bin/perl
#!/usr/bin/perl
Line 142: Line 138:
}->(5), "\n";
}->(5), "\n";
</syntaxhighlight>
</syntaxhighlight>
=== R ===
[[आर (प्रोग्रामिंग भाषा)|R (प्रोग्रामिंग लैंग्वेज)]] में, वर्तमान फ़ंक्शन का उदाहरण के लिए <code>Recall</code> उपयोग करके कॉल किया जा सकता है


=== आर ===
[[आर (प्रोग्रामिंग भाषा)]] में, वर्तमान फ़ंक्शन का उपयोग करके कॉल किया जा सकता है <code>Recall</code>. उदाहरण के लिए,
<syntaxhighlight lang="r">
<syntaxhighlight lang="r">
sapply(0:5, function(n) {
sapply(0:5, function(n) {
Line 152: Line 147:
})
})
</syntaxhighlight>
</syntaxhighlight>
हालाँकि, यह काम नहीं करेगा, यदि इसे किसी अन्य फ़ंक्शन के लिए तर्क के रूप में पारित किया जाता है, उदाहरण के लिए <code>lapply</code>, अनाम फ़ंक्शन परिभाषा के अंदर। इस मामले में, <code>sys.function(0)</code> इस्तेमाल किया जा सकता है।<ref>[https://stackoverflow.com/a/19714566 agstudy's answer] to [https://stackoverflow.com/q/19714153 Get currently called function to write anonymous recursive function]
चूँकि, यह काम नहीं करेगा, यदि इसे किसी अन्य फ़ंक्शन के लिए लॉजिक के रूप में सिद्ध किया जाता है, उदाहरण के लिए एनोनिमस फ़ंक्शन परिलैंग्वेज के अंदर <code>lapply</code>, है। इस स्थिति में, <code>sys.function(0)</code> का उपयोग किया जा सकता है।<ref>[https://stackoverflow.com/a/19714566 agstudy's answer] to [https://stackoverflow.com/q/19714153 Get currently called function to write anonymous recursive function]


at ''StackOverflow''</ref> उदाहरण के लिए, नीचे दिया गया कोड किसी सूची को पुनरावर्ती रूप से वर्गित करता है:
at ''StackOverflow''</ref> उदाहरण के लिए, नीचे दिया गया कोड किसी सूची को पुनरावर्ती रूप से वर्गित करता है:
<syntaxhighlight lang="r">
<syntaxhighlight lang="r">
(function(x) {
(function(x) {
Line 164: Line 160:
})(list(list(1, 2, 3), list(4, 5)))
})(list(list(1, 2, 3), list(4, 5)))
</syntaxhighlight>
</syntaxhighlight>
 
==संदर्भ                                                                                                                                                                                                                                                                                                                                                                                                             ==
 
==संदर्भ==
{{reflist}}
{{reflist}}
[[Category: प्रत्यावर्तन]] [[Category: उदाहरण आर कोड वाले लेख]]


[[Category: Machine Translated Page]]
[[Category:Created On 25/07/2023]]
[[Category:Created On 25/07/2023]]
[[Category:Lua-based templates]]
[[Category:Machine Translated Page]]
[[Category:Pages with script errors]]
[[Category:Short description with empty Wikidata description]]
[[Category:Templates Vigyan Ready]]
[[Category:Templates that add a tracking category]]
[[Category:Templates that generate short descriptions]]
[[Category:Templates using TemplateData]]
[[Category:उदाहरण आर कोड वाले लेख]]
[[Category:प्रत्यावर्तन]]

Latest revision as of 12:16, 10 August 2023

कंप्यूटर विज्ञान में, एनोनिमस रिकर्सन रिकर्सन (कंप्यूटर विज्ञान) है जो स्पष्ट रूप से किसी फ़ंक्शन को नाम से नहीं बुलाता है। यह या तो स्पष्ट रूप से, उच्च-क्रम वाले फ़ंक्शन का उपयोग करके किया जा सकता है - किसी फ़ंक्शन को लॉजिक के रूप में सिद्ध करना और उसे कॉल करना या परोक्ष रूप से, रिफ्लेक्शन (कंप्यूटर प्रोग्रामिंग) सुविधाओं के माध्यम से जो किसी को वर्तमान संदर्भ, विशेष रूप से वर्तमान फ़ंक्शन या कभी-कभी वर्तमान फ़ंक्शन के कॉलिंग फ़ंक्शन के आधार पर कुछ कार्यों तक पहुंचने की अनुमति देता है।

प्रोग्रामिंग अभ्यास में, जावास्क्रिप्ट में एनोनिमस रिकर्सन का विशेष रूप से उपयोग किया जाता है, जो इसका समर्थन करने के लिए रिफ्लेक्शन सुविधाएं प्रदान करता है। चूँकि, सामान्य प्रोग्रामिंग अभ्यास में, इसे व्यर्थ शैली माना जाता है, और इसके अतिरिक्त नामांकित कार्यों के साथ रिकर्सन का सुझाव दिया जाता है। इस प्रकार कार्यों को लॉजिक के रूप में स्पष्ट रूप से सिद्ध करने के माध्यम से एनोनिमस रिकर्सन किसी भी लैंग्वेज में संभव है जो लॉजिक के रूप में कार्यों का समर्थन करती है, चूँकि व्यवहार में इसका उपयोग संभवतः ही कभी किया जाता है, क्योंकि यह नाम से स्पष्ट रूप से रिकर्सन की तुलना में अधिक लंबा और कम स्पष्ट है।

सैद्धांतिक कंप्यूटर विज्ञान में, एनोनिमस रिकर्सन महत्वपूर्ण है, क्योंकि यह दर्शाता है कि कोई नामांकित कार्यों की आवश्यकता के बिना रिकर्सन प्रयुक्त कर सकता है। यह लैम्ब्डा कैलकुलस के लिए विशेष रूप से महत्वपूर्ण है, जिसमें एनोनिमस यूनरी फ़ंक्शन हैं, किन्तु किसी भी पुनरावर्ती फ़ंक्शन की गणना करने में सक्षम है। इस एनोनिमस रिकर्सन को निश्चित-बिंदु कॉम्बिनेटर के माध्यम से सामान्य रूप से उत्पादित किया जा सकता है।

उपयोग

एनोनिमस रिकर्सन का उपयोग मुख्य रूप से एनोनिमस कार्यों के लिए रिकर्सन की अनुमति देने में किया जाता है, विशेष रूप से जब वह क्लोजर (कंप्यूटर विज्ञान) बनाते हैं या फ़ंक्शन के क्लोज़र से बचने के लिए कॉलबैक (कंप्यूटर प्रोग्रामिंग) के रूप में उपयोग किए जाते हैं।

एनोनिमस रिकर्सन में मुख्य रूप से वर्तमान फ़ंक्शन को कॉल करना सम्मिलित है, जिसके परिणामस्वरूप प्रत्यक्ष रिकर्सन होता है। एनोनिमस अप्रत्यक्ष रिकर्सन संभव है, जैसे कि कॉलर (पिछले फ़ंक्शन) को कॉल करके, या, संभवतः ही कभी, कॉल स्टैक में और ऊपर जाकर, और इसे पारस्परिक रिकर्सन उत्पन्न करने के लिए श्रृंखलाबद्ध किया जा सकता है। वर्तमान फ़ंक्शन का स्व-संदर्भ ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग में इस (कंप्यूटर प्रोग्रामिंग) कीवर्ड का कार्यात्मक समकक्ष है, जो किसी को वर्तमान संदर्भ को संदर्भित करने की अनुमति देता है।

एनोनिमस रिकर्सन का उपयोग नामांकित फ़ंक्शंस के लिए भी किया जा सकता है, किन्तु उन्हें नाम से कॉल करना होता है, यह निर्दिष्ट करना कि कोई वर्तमान फ़ंक्शन पर रिकर्सन कर रहा है, या किसी को उस नाम को परिवर्तन करने की आवश्यकता के बिना फ़ंक्शन का नाम परिवर्तन करने की अनुमति देना जहां यह स्वयं कॉल करता है। चूँकि, प्रोग्रामिंग शैली के स्थिति में यह सामान्यतः नहीं किया जाता है।

विकल्प

नामांकित फ़ंक्शन

सामान्य विकल्प नामांकित फ़ंक्शंस और नामांकित रिकर्सन का उपयोग करना है। एनोनिमस फ़ंक्शन को देखते हुए, यह या तो फ़ंक्शन में नाम बाइंड करके किया जा सकता है, जैसा कि जावास्क्रिप्ट में नामांकित फ़ंक्शन एक्सप्रेशन में होता है, या फ़ंक्शन को वेरिएबल में निर्दिष्ट करके और फिर वेरिएबल को कॉल करके किया जा सकता है, जैसा कि जावास्क्रिप्ट में फ़ंक्शन स्टेटमेंट में होता है। चूँकि जो लैंग्वेजएँ एनोनिमस फ़ंक्शंस की अनुमति देती हैं, वह सामान्यतः इन फ़ंक्शंस को वेरिएबल्स (यदि प्रथम श्रेणी फ़ंक्शंस नहीं) को निर्दिष्ट करने की अनुमति देती हैं, तो अनेक लैंग्वेजएँ स्वयं फ़ंक्शन को संदर्भित करने का कोई विधि प्रदान नहीं करती हैं, और स्पष्ट रूप से एनोनिमस रिकर्सन को अस्वीकार करती हैं; उदाहरणों में गो (प्रोग्रामिंग लैंग्वेज) सम्मिलित है।[1]

उदाहरण के लिए, जावास्क्रिप्ट में फैक्टोरियल फ़ंक्शन को एनोनिमस रिकर्सन के माध्यम से परिभाषित किया जा सकता है:[2]

[1, 2, 3, 4, 5].map(function(n) {
     return (!(n > 1)) ? 1 : arguments.callee(n-1) * n;
});

नामांकित फ़ंक्शन अभिव्यक्ति का उपयोग करने के लिए पुनः लिखे जाने पर यह प्राप्त होता है:

[1, 2, 3, 4, 5].map(function factorial(n) {
     return (!(n > 1)) ? 1 : factorial(n-1) * n;
});

फ़ंक्शंस को लॉजिक के रूप में पास करना

वर्तमान फ़ंक्शन या कॉलिंग फ़ंक्शन को संदर्भित करने के लिए तंत्र के बिना भी, ऐसी लैंग्वेज में एनोनिमस रिकर्सन संभव है जो फ़ंक्शन को लॉजिक के रूप में अनुमति देता है। यह मूल पुनरावर्ती फ़ंक्शन में और मापदंड जोड़कर और पुनरावर्ती कॉल के लिए फ़ंक्शन के रूप में इस मापदंड का उपयोग करके किया जाता है। यह उच्च-क्रम फ़ंक्शन बनाता है, और इस उच्च फ़ंक्शन को पास करने से वास्तविक पुनरावर्ती फ़ंक्शन के अन्दर एनोनिमस रिकर्सन की अनुमति मिलती है। इस उच्च क्रम फ़ंक्शन पर निश्चित-बिंदु कॉम्बिनेटर प्रयुक्त करके इसे पूरी तरह से गुमनाम रूप से किया जा सकता है। यह मुख्य रूप से अकादमिक रुचि का है, विशेष रूप से यह दिखाने के लिए कि लैम्ब्डा कैलकुलस में रिकर्सन है, क्योंकि परिणामी अभिव्यक्ति मूल नामांकित रिकर्सिव फ़ंक्शन की तुलना में अधिक सम्मिश्र है। इसके विपरीत, फिक्स्ड-पॉइंटेड कॉम्बिनेटर्स के उपयोग को सामान्य रूप से एनोनिमस रिकर्सन के रूप में संदर्भित किया जा सकता है, क्योंकि यह उनका उल्लेखनीय उपयोग है, चूँकि उनके पास अन्य अनुप्रयोग हैं।[3][4]

इसे नीचे पायथन फर्स्ट रिकर्सन नामक मानक का उपयोग करके चित्रित किया गया है:

def fact(n):
    if n == 0:
        return 1
    return n * fact(n - 1)

उच्च-क्रम फ़ंक्शन का उपयोग करना जिससे टॉप-लेबल फ़ंक्शन किसी लॉजिक पर अनोनीमौसली रूप से रिकर्सन कर सकते है, किन्तु फिर भी लॉजिक के रूप में मानक पुनरावर्ती फ़ंक्शन की आवश्यकता होती है:

def fact0(n0):
    if n0 == 0:
        return 1
    return n0 * fact0(n0 - 1)
fact1 = lambda f, n1: 1 if n1 == 0 else n1 * f(n1 - 1)
fact = lambda n: fact1(fact0, n)

हम फ़ंक्शन लॉजिक को कॉल में पास करके मानक पुनरावर्ती फ़ंक्शन को समाप्त कर सकते हैं:

fact1 = lambda f, n1: 1 if n1 == 0 else n1 * f(f, n1 - 1)
fact = lambda n: fact1(fact1, n)

दूसरी पंक्ति को सामान्य हायर-आर्डर फ़ंक्शन द्वारा प्रतिस्थापित किया जा सकता है जिसे कॉम्बिनेटर लॉजिक कहा जाता है:

F = lambda f: (lambda x: f(f, x))
fact1 = lambda f, n1: 1 if n1 == 0 else n1 * f(f, n1 - 1)
fact = F(fact1)

एनोनिमस रूप से लिखा गया:[5]

(lambda f: (lambda x: f(f, x))) \
(lambda g, n1: 1 if n1 == 0 else n1 * g(g, n1 - 1))

लैम्ब्डा कैलकुलस में, जो केवल ही चर के कार्यों का उपयोग करता है, यह फिक्स्ड-पॉइंट कॉम्बिनेटर के माध्यम से किया जा सकता है। पहले दो वेरिएबल्स के उच्च-क्रम वाले फ़ंक्शन को एकल वेरिएबल का फ़ंक्शन बनाएं, जो कर्र्यिंग द्वारा सीधे फ़ंक्शन लौटाता है:

fact1 = lambda f: (lambda n1: 1 if n1 == 0 else n1 * f(f)(n1 - 1))
fact = fact1(fact1)

यहां दो हायर-आर्डर फ़ंक्शन को अपने आप में प्रयुक्त करने वाले ऑपरेशन हैं: f(f) पहली पंक्ति में और fact1(fact1) क्षण में। कॉम्बिनेटरी लॉजिक में दूसरे दोहरे अनुप्रयोग का गुणनखंड करने से परिणाम मिलते हैं:

C = lambda x: x(x)
fact1 = lambda f: (lambda n1: 1 if n1 == 0 else n1 * f(f)(n1 - 1))
fact = C(fact1)

अन्य दोहरे अनुप्रयोग प्रतिफलों को ध्यान में रखते हुए:

C = lambda x: x(x)
D = lambda f: (lambda x: f(lambda v: x(x)(v)))
fact1 = lambda g: (lambda n1: 1 if n1 == 0 else n1 * g(n1 - 1))
fact = C(D(fact1))

दो कॉम्बिनेटरों को में मिलाने से फिक्स्ड-पॉइंट कॉम्बिनेटर प्राप्त होता है:

C = lambda x: x(x)
D = lambda f: (lambda x: f(lambda v: x(x)(v)))
Y = lambda y: C(D(y))
fact1 = lambda g: (lambda n1: 1 if n1 == 0 else n1 * g(n1 - 1))
fact = Y(fact1)

Y कॉम्बिनेटर का विस्तार करने से परिणाम मिलते हैं:

Y = lambda f: (lambda x: f(lambda v: x(x)(v))) \
              (lambda x: f(lambda v: x(x)(v)))
fact1 = lambda g: (lambda n1: 1 if n1 == 0 else n1 * g(n1 - 1))
fact = Y(fact1)

इनके संयोजन से लैम्ब्डा कैलकुलस (एकल चर के एनोनिमस कार्य) में फैक्टोरियल की पुनरावर्ती परिलैंग्वेज प्राप्त होती है:[6]

(lambda f: (lambda x: f(lambda v: x(x)(v)))
           (lambda x: f(lambda v: x(x)(v)))) \
(lambda g: (lambda n1: 1 if n1 == 0 else n1 * g(n1 - 1)))

उदाहरण

एपीएल

एपीएल (प्रोग्रामिंग लैंग्वेज) में वर्तमान डीएफएनएस के माध्यम से पहुंच योग्य है। यह एनोनिमस रिकर्सन की अनुमति देता है, जैसे कि फैक्टोरियल के इस कार्यान्वयन में:

   {0=⍵:1  × -1} 5
120
   {0=⍵:1  × -1}¨ 10    ⍝ applied to each element of 0 to 9
1 1 2 6 24 120 720 5040 40320 362880

जावास्क्रिप्ट

जावास्क्रिप्ट में, वर्तमान फ़ंक्शन arguments.callee के माध्यम से एक्सेस किया जा सकता है , जबकि कॉलिंग फ़ंक्शन को arguments.caller माध्यम से पहुंच योग्य है ये एनोनिमस रिकर्सन की अनुमति देते हैं, जैसे कि फैक्टोरियल के इस कार्यान्वयन में:[2]

[1, 2, 3, 4, 5].map(function(n) {
    return (!(n > 1)) ? 1 : arguments.callee(n - 1) * n;
});

पर्ल

पर्ल 5.16 से प्रारंभ होकर, वर्तमान सबरूटीन __SUB__ माध्यम से पहुंच योग्य है जो वर्तमान सबरूटीन का संदर्भ लौटाता है, या इस प्रकारundef सबरूटीन के बाहर.[7] यह एनोनिमस रिकर्सन की अनुमति देता है, जैसे कि फैक्टोरियल के निम्नलिखित कार्यान्वयन में:

#!/usr/bin/perl
use feature ":5.16";

print sub {
    my $x = shift;
    $x > 0
    ? $x * __SUB__->( $x - 1 )
    : 1;
}->(5), "\n";

R

R (प्रोग्रामिंग लैंग्वेज) में, वर्तमान फ़ंक्शन का उदाहरण के लिए Recall उपयोग करके कॉल किया जा सकता है

sapply(0:5, function(n) {
  if (n == 0) return(1)
  n * Recall(n - 1)
})

चूँकि, यह काम नहीं करेगा, यदि इसे किसी अन्य फ़ंक्शन के लिए लॉजिक के रूप में सिद्ध किया जाता है, उदाहरण के लिए एनोनिमस फ़ंक्शन परिलैंग्वेज के अंदर lapply, है। इस स्थिति में, sys.function(0) का उपयोग किया जा सकता है।[8] उदाहरण के लिए, नीचे दिया गया कोड किसी सूची को पुनरावर्ती रूप से वर्गित करता है:

(function(x) {
  if (is.list(x)) {
    lapply(x, sys.function(0))
  } else {
    x^2
  }
})(list(list(1, 2, 3), list(4, 5)))

संदर्भ

  1. Issue 226: It's impossible to recurse a anonymous function in Go without workarounds.
  2. 2.0 2.1 answer by olliej, Oct 25 '08 to "Why was the arguments.callee.caller property deprecated in JavaScript?", StackOverflow
  3. This terminology appear to be largely folklore, but it does appear in the following:
    • Trey Nash, Accelerated C# 2008, Apress, 2007, ISBN 1-59059-873-3, p. 462—463. Derived substantially from Wes Dyer's blog (see next item).
    • Wes Dyer Anonymous Recursion in C#, February 02, 2007, contains a substantially similar example found in the book above, but accompanied by more discussion.
  4. The If Works Deriving the Y combinator, January 10th, 2008
  5. Hugo Walter's answer to "Can a lambda function call itself recursively in Python?"
  6. Nux's answer to "Can a lambda function call itself recursively in Python?"
  7. Perldoc, "The 'current_sub' feature", perldoc feature
  8. agstudy's answer to Get currently called function to write anonymous recursive function at StackOverflow