प्रथम श्रेणी फंक्शन: Difference between revisions

From Vigyanwiki
mNo edit summary
mNo edit summary
Line 1: Line 1:
[[कंप्यूटर विज्ञान]] में, [[समारोह (प्रोग्रामिंग)|प्रोग्रामिंग]] भाषा को प्रथम श्रेणी के कार्यों वाला कहा जाता है यदि यह कार्य को प्रथम श्रेणी के विषय वस्तु के रूप में मानता है। इसका अर्थ यह है कि भाषा अन्य कार्यों के लिए तर्क के रूप में कार्यों को पारित करने, उन्हें अन्य कार्यों से मूल्यों के रूप में वापस करने और उन्हें चर को निर्दिष्ट करने या डेटा संरचनाओं में संग्रहीत करने का समर्थन करती है।<ref>{{cite book|first1=Harold|last1=Abelson|authorlink1=Harold Abelson|first2=Gerald Jay|last2=Sussman|authorlink2=Gerald Jay Sussman|title=कंप्यूटर प्रोग्राम की संरचना और व्याख्या|at=[https://archive.org/details/structureinterpr00abel/page/ Formulating Abstractions with Higher-Order Procedures]|publisher=MIT Press|year=1984|isbn=0-262-01077-1|url=https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-12.html#%_sec_1.3}}</ref> कुछ प्रोग्रामिंग भाषा सिद्धांतकारों को अज्ञात कार्यों के लिए भी समर्थन की आवश्यकता होती है।<ref name="test">[http://www.worldcat.org/oclc/222529448 Programming language pragmatics], by Michael Lee Scott, section 11.2 "Functional Programming".</ref> प्रथम श्रेणी के कार्यों वाली भाषाओं में, कार्यों के [[नाम (कंप्यूटर विज्ञान)]] की कोई विशेष स्थिति नहीं है; उन्हें कार्य   प्रकार के साथ साधारण [[चर (कंप्यूटर विज्ञान)]] की तरह माना जाता है।<ref>{{cite journal |title=The Implementation of Lua 5.0 |author1=Roberto Ierusalimschy |author1-link=Roberto Ierusalimschy |author2=Luiz Henrique de Figueiredo |author3=Waldemar Celes |journal=Journal of Universal Computer Science |doi=10.3217/jucs-011-07-1159 |doi-access=free |volume=11 |issue=7 |date=2005 |pages=1159–1176}}</ref> यह शब्द [[क्रिस्टोफर स्ट्रेची]] द्वारा 1960 के दशक के मध्य में प्रथम श्रेणी के नागरिकों के रूप में कार्यों के संदर्भ में गढ़ा गया था।<ref name=strachey>{{cite journal|last1=Burstall |first1=Rod |last2=Strachey |first2=Christopher |title=प्रोग्रामिंग भाषाओं को समझना|journal=[[Higher-Order and Symbolic Computation]] |date=2000 |volume=13 |issue=52 |pages=11–49 |doi=10.1023/A:1010052305354 |s2cid=1989590 |url=http://www.cs.cmu.edu/~crary/819-f09/Strachey67.pdf |url-status=bot: unknown |archiveurl=https://web.archive.org/web/20100216060948/http://www.cs.cmu.edu/~crary/819-f09/Strachey67.pdf |archivedate=February 16, 2010 }} (also  on 2010-02-16</ref>
[[कंप्यूटर विज्ञान]] में, [[समारोह (प्रोग्रामिंग)|प्रोग्रामिंग]] भाषा को प्रथम श्रेणी के कार्यों वाला कहा जाता है यदि यह कार्य को प्रथम श्रेणी के विषय वस्तु के रूप में मानता है। इसका अर्थ यह है कि भाषा अन्य कार्यों के लिए तर्क के रूप में कार्यों को पारित करने, उन्हें अन्य कार्यों से मूल्यों के रूप में वापस करने और उन्हें चर को निर्दिष्ट करने या डेटा संरचनाओं में संग्रहीत करने का समर्थन करती है।<ref>{{cite book|first1=Harold|last1=Abelson|authorlink1=Harold Abelson|first2=Gerald Jay|last2=Sussman|authorlink2=Gerald Jay Sussman|title=कंप्यूटर प्रोग्राम की संरचना और व्याख्या|at=[https://archive.org/details/structureinterpr00abel/page/ Formulating Abstractions with Higher-Order Procedures]|publisher=MIT Press|year=1984|isbn=0-262-01077-1|url=https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-12.html#%_sec_1.3}}</ref> कुछ प्रोग्रामिंग भाषा सिद्धांतकारों को, अज्ञात कार्यों के लिए भी समर्थन की आवश्यकता होती है।<ref name="test">[http://www.worldcat.org/oclc/222529448 Programming language pragmatics], by Michael Lee Scott, section 11.2 "Functional Programming".</ref> प्रथम श्रेणी के कार्यों वाली भाषाओं में, कार्यों के [[नाम (कंप्यूटर विज्ञान)]] की कोई विशेष स्थिति नहीं है; उन्हें कार्य प्रकार के साथ साधारण [[चर (कंप्यूटर विज्ञान)]] की तरह माना जाता है।<ref>{{cite journal |title=The Implementation of Lua 5.0 |author1=Roberto Ierusalimschy |author1-link=Roberto Ierusalimschy |author2=Luiz Henrique de Figueiredo |author3=Waldemar Celes |journal=Journal of Universal Computer Science |doi=10.3217/jucs-011-07-1159 |doi-access=free |volume=11 |issue=7 |date=2005 |pages=1159–1176}}</ref> यह शब्द [[क्रिस्टोफर स्ट्रेची]] द्वारा 1960 के दशक के मध्य में प्रथम श्रेणी के विषय वस्तु के रूप में कार्यों के संदर्भ में बनाया गया था।<ref name=strachey>{{cite journal|last1=Burstall |first1=Rod |last2=Strachey |first2=Christopher |title=प्रोग्रामिंग भाषाओं को समझना|journal=[[Higher-Order and Symbolic Computation]] |date=2000 |volume=13 |issue=52 |pages=11–49 |doi=10.1023/A:1010052305354 |s2cid=1989590 |url=http://www.cs.cmu.edu/~crary/819-f09/Strachey67.pdf |url-status=bot: unknown |archiveurl=https://web.archive.org/web/20100216060948/http://www.cs.cmu.edu/~crary/819-f09/Strachey67.pdf |archivedate=February 16, 2010 }} (also  on 2010-02-16</ref>


[[कार्यात्मक प्रोग्रामिंग]] शैली के लिए प्रथम श्रेणी के कार्य आवश्यक हैं, जिसमें उच्च-क्रम के कार्यों का उपयोग एक मानक अभ्यास है। उच्च-क्रम वाले कार्य   का एक सरल उदाहरण मानचित्र (उच्च-क्रम कार्य  ) कार्य   है, जो इसके तर्कों, कार्य  और सूची के रूप में लेता है, और सूची के प्रत्येक सदस्य को कार्य   लागू करके बनाई गई सूची देता है। एक भाषा के लिए मानचित्र का समर्थन करने के लिए, उसे एक तर्क के रूप में कार्य को पारित करने का समर्थन करना चाहिए।
[[कार्यात्मक प्रोग्रामिंग]] शैली के लिए प्रथम श्रेणी के कार्य आवश्यक हैं, जिसमें उच्च-क्रम के कार्यों का उपयोग एक मानक अभ्यास है। उच्च-क्रम वाले कार्य का एक सरल उदाहरण आलेखन कार्य है, जो इसके तर्कों, कार्य  और सूची के रूप में लेता है, और सूची के प्रत्येक सदस्य को कार्य लागू करके बनाई गई सूची देता है। एक भाषा के लिए आलेखन का समर्थन करने के लिए, उसे एक तर्क के रूप में कार्य को पारित करने का समर्थन करना चाहिए।


कार्यों को तर्कों के रूप में पास करने या उन्हें परिणाम के रूप में वापस करने में कुछ कार्यान्वयन कठिनाइयाँ हैं, विशेष रूप से [[नेस्टेड समारोह|नेस्टेड कार्य]] और अनाम कार्य में पेश किए गए [[गैर-स्थानीय चर]] की उपस्थिति में। ऐतिहासिक रूप से, इन्हें [[फंगस की समस्या]] कहा जाता था, यह नाम कार्य  तर्क से आता है।<ref>[[Joel Moses]]. [https://dspace.mit.edu/handle/1721.1/5854 "The Function of FUNCTION in LISP, or Why the FUNARG Problem Should be Called the Environment Problem"]. MIT AI Memo 199, 1970.</ref> प्रारंभिक अनिवार्य भाषाओं में इन समस्याओं को या तो परिणाम प्रकार (जैसे [[ALGOL 60]], [[पास्कल (प्रोग्रामिंग भाषा)]]) के रूप में कार्यों का समर्थन नहीं करने या नेस्टेड कार्यों को छोड़ने और इस प्रकार गैर-स्थानीय चर (जैसे C (प्रोग्रामिंग भाषा)) से बचा गया था। शुरुआती कार्यात्मक भाषा [[लिस्प (प्रोग्रामिंग भाषा)]] ने [[गतिशील स्कोपिंग]] का दृष्टिकोण अपनाया, जहां गैर-स्थानीय चर उस चर की निकटतम परिभाषा को उस बिंदु पर संदर्भित करते हैं जहां कार्य  को परिभाषित किया गया था, बजाय जहां इसे परिभाषित किया गया था। योजना (प्रोग्रामिंग लैंग्वेज) में [[लेक्सिकली स्कोप्ड]] प्रथम श्रेणी के कार्यों के लिए उचित समर्थन पेश किया गया था और नंगे [[समारोह सूचक|कार्य  सूचक]] के बजाय क्लोजर (कंप्यूटर विज्ञान) के रूप में कार्यों के संदर्भों को संभालने की आवश्यकता है,<ref name="strachey" />जो बदले में [[कचरा संग्रह (कंप्यूटर विज्ञान)]] को एक आवश्यकता बनाता है।
कार्यों को तर्कों के रूप में पास करने या उन्हें परिणाम के रूप में वापस करने में कुछ कार्यान्वयन कठिनाइयाँ हैं, विशेष रूप से [[नेस्टेड समारोह|नेस्टेड कार्य]] और अनाम कार्य में पेश किए गए [[गैर-स्थानीय चर]] की उपस्थिति में। ऐतिहासिक रूप से, इन्हें [[फंगस की समस्या]] कहा जाता था, यह नाम कार्य  तर्क से आता है।<ref>[[Joel Moses]]. [https://dspace.mit.edu/handle/1721.1/5854 "The Function of FUNCTION in LISP, or Why the FUNARG Problem Should be Called the Environment Problem"]. MIT AI Memo 199, 1970.</ref> प्रारंभिक अनिवार्य भाषाओं में इन समस्याओं को या तो परिणाम प्रकार (जैसे [[ALGOL 60]], [[पास्कल (प्रोग्रामिंग भाषा)]]) के रूप में कार्यों का समर्थन नहीं करने या नेस्टेड कार्यों को छोड़ने और इस प्रकार गैर-स्थानीय चर (जैसे C (प्रोग्रामिंग भाषा)) से बचा गया था। शुरुआती कार्यात्मक भाषा [[लिस्प (प्रोग्रामिंग भाषा)]] ने [[गतिशील स्कोपिंग]] का दृष्टिकोण अपनाया, जहां गैर-स्थानीय चर उस चर की निकटतम परिभाषा को उस बिंदु पर संदर्भित करते हैं जहां कार्य  को परिभाषित किया गया था, बजाय जहां इसे परिभाषित किया गया था। योजना (प्रोग्रामिंग लैंग्वेज) में [[लेक्सिकली स्कोप्ड]] प्रथम श्रेणी के कार्यों के लिए उचित समर्थन पेश किया गया था और नंगे [[समारोह सूचक|कार्य  सूचक]] के बजाय क्लोजर (कंप्यूटर विज्ञान) के रूप में कार्यों के संदर्भों को संभालने की आवश्यकता है,<ref name="strachey" />जो बदले में [[कचरा संग्रह (कंप्यूटर विज्ञान)]] को एक आवश्यकता बनाता है।
Line 10: Line 10:


=== उच्च-क्रम के कार्य: तर्कों के रूप में कार्यों को पारित करना ===
=== उच्च-क्रम के कार्य: तर्कों के रूप में कार्यों को पारित करना ===
{{further information|Higher-order function}}
उन भाषाओं में जहां कार्य प्रथम श्रेणी के नागरिक हैं, कार्यों को अन्य कार्यों के तर्कों के रूप में उसी तरह पारित किया जा सकता है जैसे अन्य मान (तर्क के रूप में किसी अन्य कार्य को लेने वाले कार्य को उच्च-क्रम कार्य  कहा जाता है)। भाषा हास्केल (प्रोग्रामिंग भाषा) में:
उन भाषाओं में जहां कार्य प्रथम श्रेणी के नागरिक हैं, कार्यों को अन्य कार्यों के तर्कों के रूप में उसी तरह पारित किया जा सकता है जैसे अन्य मान (तर्क के रूप में किसी अन्य कार्य को लेने वाले कार्य को उच्च-क्रम कार्य  कहा जाता है)। भाषा हास्केल (प्रोग्रामिंग भाषा) में:
<syntaxhighlight lang="haskell">
<syntaxhighlight lang="haskell">
Line 27: Line 26:


=== अनाम और नेस्टेड कार्य ===
=== अनाम और नेस्टेड कार्य ===
{{further information|Anonymous function|Nested function}}
अधिक जानकारी: अनाम फ़ंक्शन और नेस्टेड फ़ंक्शन
अज्ञात कार्यों का समर्थन करने वाली भाषाओं में, हम इस तरह के कार्य   को उच्च-क्रम कार्य   के तर्क के रूप में पास कर सकते हैं:
 
अज्ञात कार्यों का समर्थन करने वाली भाषाओं में, हम इस तरह के कार्य को उच्च-क्रम कार्य के तर्क के रूप में पास कर सकते हैं:
<syntaxhighlight lang="haskell">
<syntaxhighlight lang="haskell">
main = map (\x -> 3 * x + 1) [1, 2, 3, 4, 5]
main = map (\x -> 3 * x + 1) [1, 2, 3, 4, 5]
Line 44: Line 44:
</syntaxhighlight>
</syntaxhighlight>


 
'''<br />गैर-स्थानीय चर और क्लोजर'''
=== गैर-स्थानीय चर और क्लोजर ===
{{further information|Non-local variable|Closure (computer science)}}


एक बार जब हमारे पास गुमनाम या नेस्टेड कार्य होते हैं, तो उनके लिए अपने शरीर के बाहर के चरों को संदर्भित करना स्वाभाविक हो जाता है (जिन्हें गैर-स्थानीय चर कहा जाता है):
एक बार जब हमारे पास गुमनाम या नेस्टेड कार्य होते हैं, तो उनके लिए अपने शरीर के बाहर के चरों को संदर्भित करना स्वाभाविक हो जाता है (जिन्हें गैर-स्थानीय चर कहा जाता है):
Line 54: Line 52:
         in map (\x -> a * x + b) [1, 2, 3, 4, 5]
         in map (\x -> a * x + b) [1, 2, 3, 4, 5]
</syntaxhighlight>
</syntaxhighlight>
यदि कार्य   को नंगे कार्य   पॉइंटर्स के साथ दर्शाया जाता है, तो हम अब यह नहीं जान सकते हैं कि कार्य  के शरीर के बाहर का मान इसे कैसे पारित किया जाना चाहिए, और इसके कारण एक क्लोजर को मैन्युअल रूप से बनाने की आवश्यकता होती है। इसलिए हम यहाँ प्रथम श्रेणी के कार्यों की बात नहीं कर सकते।
यदि कार्य को नंगे कार्य पॉइंटर्स के साथ दर्शाया जाता है, तो हम अब यह नहीं जान सकते हैं कि कार्य  के शरीर के बाहर का मान इसे कैसे पारित किया जाना चाहिए, और इसके कारण एक क्लोजर को मैन्युअल रूप से बनाने की आवश्यकता होती है। इसलिए हम यहाँ प्रथम श्रेणी के कार्यों की बात नहीं कर सकते।


<syntaxhighlight lang="c">
<syntaxhighlight lang="c">

Revision as of 21:27, 26 June 2023

कंप्यूटर विज्ञान में, प्रोग्रामिंग भाषा को प्रथम श्रेणी के कार्यों वाला कहा जाता है यदि यह कार्य को प्रथम श्रेणी के विषय वस्तु के रूप में मानता है। इसका अर्थ यह है कि भाषा अन्य कार्यों के लिए तर्क के रूप में कार्यों को पारित करने, उन्हें अन्य कार्यों से मूल्यों के रूप में वापस करने और उन्हें चर को निर्दिष्ट करने या डेटा संरचनाओं में संग्रहीत करने का समर्थन करती है।[1] कुछ प्रोग्रामिंग भाषा सिद्धांतकारों को, अज्ञात कार्यों के लिए भी समर्थन की आवश्यकता होती है।[2] प्रथम श्रेणी के कार्यों वाली भाषाओं में, कार्यों के नाम (कंप्यूटर विज्ञान) की कोई विशेष स्थिति नहीं है; उन्हें कार्य प्रकार के साथ साधारण चर (कंप्यूटर विज्ञान) की तरह माना जाता है।[3] यह शब्द क्रिस्टोफर स्ट्रेची द्वारा 1960 के दशक के मध्य में प्रथम श्रेणी के विषय वस्तु के रूप में कार्यों के संदर्भ में बनाया गया था।[4]

कार्यात्मक प्रोग्रामिंग शैली के लिए प्रथम श्रेणी के कार्य आवश्यक हैं, जिसमें उच्च-क्रम के कार्यों का उपयोग एक मानक अभ्यास है। उच्च-क्रम वाले कार्य का एक सरल उदाहरण आलेखन कार्य है, जो इसके तर्कों, कार्य और सूची के रूप में लेता है, और सूची के प्रत्येक सदस्य को कार्य लागू करके बनाई गई सूची देता है। एक भाषा के लिए आलेखन का समर्थन करने के लिए, उसे एक तर्क के रूप में कार्य को पारित करने का समर्थन करना चाहिए।

कार्यों को तर्कों के रूप में पास करने या उन्हें परिणाम के रूप में वापस करने में कुछ कार्यान्वयन कठिनाइयाँ हैं, विशेष रूप से नेस्टेड कार्य और अनाम कार्य में पेश किए गए गैर-स्थानीय चर की उपस्थिति में। ऐतिहासिक रूप से, इन्हें फंगस की समस्या कहा जाता था, यह नाम कार्य तर्क से आता है।[5] प्रारंभिक अनिवार्य भाषाओं में इन समस्याओं को या तो परिणाम प्रकार (जैसे ALGOL 60, पास्कल (प्रोग्रामिंग भाषा)) के रूप में कार्यों का समर्थन नहीं करने या नेस्टेड कार्यों को छोड़ने और इस प्रकार गैर-स्थानीय चर (जैसे C (प्रोग्रामिंग भाषा)) से बचा गया था। शुरुआती कार्यात्मक भाषा लिस्प (प्रोग्रामिंग भाषा) ने गतिशील स्कोपिंग का दृष्टिकोण अपनाया, जहां गैर-स्थानीय चर उस चर की निकटतम परिभाषा को उस बिंदु पर संदर्भित करते हैं जहां कार्य को परिभाषित किया गया था, बजाय जहां इसे परिभाषित किया गया था। योजना (प्रोग्रामिंग लैंग्वेज) में लेक्सिकली स्कोप्ड प्रथम श्रेणी के कार्यों के लिए उचित समर्थन पेश किया गया था और नंगे कार्य सूचक के बजाय क्लोजर (कंप्यूटर विज्ञान) के रूप में कार्यों के संदर्भों को संभालने की आवश्यकता है,[4]जो बदले में कचरा संग्रह (कंप्यूटर विज्ञान) को एक आवश्यकता बनाता है।

अवधारणाएं

इस खंड में, हम तुलना करते हैं कि विशेष प्रोग्रामिंग मुहावरे एक कार्यात्मक भाषा में प्रथम श्रेणी के कार्यों (हास्केल (प्रोग्रामिंग भाषा)) की तुलना में एक अनिवार्य भाषा की तुलना में जहां कार्य द्वितीय श्रेणी के नागरिक हैं (सी (प्रोग्रामिंग भाषा))।

उच्च-क्रम के कार्य: तर्कों के रूप में कार्यों को पारित करना

उन भाषाओं में जहां कार्य प्रथम श्रेणी के नागरिक हैं, कार्यों को अन्य कार्यों के तर्कों के रूप में उसी तरह पारित किया जा सकता है जैसे अन्य मान (तर्क के रूप में किसी अन्य कार्य को लेने वाले कार्य को उच्च-क्रम कार्य कहा जाता है)। भाषा हास्केल (प्रोग्रामिंग भाषा) में:

map :: (a -> b) -> [a] -> [b]
map f []     = []
map f (x:xs) = f x : map f xs

भाषाएं जहां कार्य प्रथम श्रेणी के नहीं होते हैं, फिर भी कार्य पॉइंटर्स या डेलिगेट (सीएलआई) जैसे सुविधाओं के उपयोग के माध्यम से उच्च-क्रम के कार्यों को लिखने की अनुमति देते हैं। भाषा सी (प्रोग्रामिंग भाषा) में:

void map(int (*f)(int), int x[], size_t n) {
    for (int i = 0; i < n; i++)
        x[i] = f(x[i]);
}

दो दृष्टिकोणों के बीच कई अंतर हैं जो सीधे प्रथम श्रेणी के कार्यों के समर्थन से संबंधित नहीं हैं। हास्केल नमूना सूची (कंप्यूटिंग) पर काम करता है, जबकि सी नमूना सरणी डेटा संरचना पर काम करता है। दोनों संबंधित भाषाओं में सबसे प्राकृतिक यौगिक डेटा संरचनाएं हैं और सी नमूना को लिंक्ड सूचियों पर संचालित करने से यह अनावश्यक रूप से जटिल हो जाता। यह इस तथ्य के लिए भी जिम्मेदार है कि सी कार्य को एक अतिरिक्त पैरामीटर की आवश्यकता होती है (सरणी का आकार देते हुए।) सी कार्य सरणी को जगह में अद्यतन करता है, कोई मूल्य नहीं लौटाता है, जबकि हास्केल डेटा संरचनाओं में लगातार डेटा संरचना होती है (एक नई सूची वापस लौटा दिया जाता है जबकि पुराना बरकरार रहता है।) हास्केल नमूना सूची को पार करने के लिए पुनरावर्तन का उपयोग करता है, जबकि सी नमूना पुनरावृत्ति का उपयोग करता है। दोबारा, यह दोनों भाषाओं में इस कार्य को व्यक्त करने का सबसे स्वाभाविक तरीका है, लेकिन हास्केल नमूना आसानी से एक गुना (उच्च-क्रम कार्य ) और सी नमूना प्रत्यावर्तन के संदर्भ में व्यक्त किया जा सकता था। अंत में, हास्केल कार्य में एक बहुरूपता (कंप्यूटर विज्ञान) प्रकार है, क्योंकि यह सी द्वारा समर्थित नहीं है, हमने सभी प्रकार के चर को स्थिर प्रकार के लिए तय किया है int.

अनाम और नेस्टेड कार्य

अधिक जानकारी: अनाम फ़ंक्शन और नेस्टेड फ़ंक्शन

अज्ञात कार्यों का समर्थन करने वाली भाषाओं में, हम इस तरह के कार्य को उच्च-क्रम कार्य के तर्क के रूप में पास कर सकते हैं:

main = map (\x -> 3 * x + 1) [1, 2, 3, 4, 5]

ऐसी भाषा में जो अज्ञात कार्यों का समर्थन नहीं करती है, हमें इसे इसके बजाय नाम से बांधना होगा:

int f(int x) {
    return 3 * x + 1;
}

int main() {
    int list[] = {1, 2, 3, 4, 5};
    map(f, list, 5);
}


गैर-स्थानीय चर और क्लोजर

एक बार जब हमारे पास गुमनाम या नेस्टेड कार्य होते हैं, तो उनके लिए अपने शरीर के बाहर के चरों को संदर्भित करना स्वाभाविक हो जाता है (जिन्हें गैर-स्थानीय चर कहा जाता है):

main = let a = 3
           b = 1
        in map (\x -> a * x + b) [1, 2, 3, 4, 5]

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

typedef struct {
    int (*f)(int, int, int);
    int *a;
    int *b;
} closure_t;

void map(closure_t *closure, int x[], size_t n) {
    for (int i = 0; i < n; ++i)
        x[i] = (*closure->f)(*closure->a, *closure->b, x[i]);
}

int f(int a, int b, int x) {
    return a * x + b;
}

void main() {
    int l[] = {1, 2, 3, 4, 5};
    int a = 3;
    int b = 1;
    closure_t closure = {f, &a, &b};
    map(&closure, l, 5);
}

यह भी ध्यान दें कि map अब दो से संबंधित कार्यों के लिए विशिष्ट है intउनके पर्यावरण के बाहर है। इसे अधिक आम तौर पर सेट किया जा सकता है, लेकिन इसके लिए अधिक बॉयलरप्लेट कोड की आवश्यकता होती है। अगर f एक नेस्टेड कार्य होता हम अभी भी एक ही समस्या में भाग लेते और यही कारण है कि वे सी में समर्थित नहीं हैं।[6]


उच्च-क्रम के कार्य: परिणाम के रूप में कार्य लौटाना

किसी कार्य को वापस करते समय, हम वास्तव में उसके समापन को वापस कर रहे हैं। सी उदाहरण में क्लोजर द्वारा कब्जा कर लिया गया कोई भी स्थानीय चर दायरे से बाहर हो जाएगा, जब हम क्लोजर बनाने वाले कार्य से वापस आ जाएंगे। बाद के बिंदु पर बंद करने के लिए मजबूर करने से अपरिभाषित व्यवहार होगा, संभवतः ढेर को दूषित कर देगा। इसे ऊपर की ओर फनर्ग समस्या के रूप में जाना जाता है।

चरों को कार्य सौंपना

असाइनमेंट (कंप्यूटर विज्ञान) वेरिएबल (कंप्यूटर साइंस) के लिए कार्य करता है और उन्हें (वैश्विक) डेटास्ट्रक्चर के अंदर संग्रहीत करने से संभावित रूप से समान कठिनाइयों से पीड़ित होता है।

f :: [[Integer] -> [Integer]]
f = let a = 3
        b = 1
     in [map (\x -> a * x + b), map (\x -> b * x + a)]


कार्यों की समानता

जैसा कि कोई समानता के लिए अधिकांश शाब्दिक और मूल्यों का परीक्षण कर सकता है, यह पूछना स्वाभाविक है कि क्या कोई प्रोग्रामिंग भाषा समानता के लिए परीक्षण कार्यों का समर्थन कर सकती है। आगे के निरीक्षण पर, यह प्रश्न अधिक कठिन प्रतीत होता है और व्यक्ति को कई प्रकार की कार्य समानता के बीच अंतर करना पड़ता है:[7]

विस्तारात्मक समानता
दो कार्यों f और g को व्यापक रूप से समान माना जाता है यदि वे सभी इनपुट के लिए अपने आउटपुट पर सहमत होते हैं (∀x. f(x) = g(x))। समानता की इस परिभाषा के तहत, उदाहरण के लिए, एक स्थिर छँटाई एल्गोरिथ्म के किसी भी दो कार्यान्वयन, जैसे कि सम्मिलन छँटाई और मर्ज छँटाई, को समान माना जाएगा। विस्तृत समानता पर निर्णय लेना सामान्य रूप से अनिर्णीत समस्या है और यहां तक ​​कि परिमित डोमेन वाले कार्यों के लिए भी अक्सर अट्रैक्टिव होता है। इस कारण से कोई प्रोग्रामिंग भाषा कार्य समानता को विस्तारित समानता के रूप में लागू नहीं करती है।
गहन समानता
आकस्मिक समानता के तहत, दो कार्यों f और g को समान माना जाता है यदि उनकी आंतरिक संरचना समान हो। इस तरह की समानता व्याख्या की गई भाषाओं में कार्य निकायों के स्रोत कोड (जैसे व्याख्या किए गए लिस्प 1.5 में) या संकलित भाषाओं में वस्तु कोड की तुलना करके कार्यान्वित की जा सकती है। आकस्मिक समानता का तात्पर्य विस्तारात्मक समानता से है (यह मानते हुए कि कार्य नियतात्मक हैं और उनमें कोई छिपा हुआ इनपुट नहीं है, जैसे कि कार्यक्रम गणक या एक परिवर्तनशील वैश्विक चर।)
संदर्भ समानता
विस्तारात्मक और गहन समानता को लागू करने की अव्यावहारिकता को देखते हुए, समानता के लिए परीक्षण कार्यों का समर्थन करने वाली अधिकांश भाषाएं संदर्भ समानता का उपयोग करती हैं। सभी कार्यों या क्लोजर को एक अद्वितीय पहचानकर्ता (आमतौर पर कार्य बॉडी या क्लोजर का पता) असाइन किया जाता है और पहचानकर्ता की समानता के आधार पर समानता तय की जाती है। दो अलग-अलग परिभाषित, लेकिन अन्यथा समान कार्य परिभाषाओं को असमान माना जाएगा। संदर्भपरक समानता का तात्पर्य गहन और विस्तारात्मक समानता से है। रेफरेंशियल समानता संदर्भित पारदर्शिता को तोड़ती है और इसलिए हास्केल जैसी शुद्धता (कंप्यूटर विज्ञान) भाषाओं में समर्थित नहीं है।

प्रकार सिद्धांत

प्रकार सिद्धांत में, प्रकार ए के मूल्यों को स्वीकार करने वाले कार्यों के प्रकार और प्रकार बी के मूल्यों को वापस करने के लिए ए → बी या बी के रूप में लिखा जा सकता हैए</सुप>। करी-हावर्ड पत्राचार में, प्रकार्य प्रकार तार्किक निहितार्थ से संबंधित हैं; लैम्ब्डा एब्स्ट्रैक्शन काल्पनिक मान्यताओं के निर्वहन से मेल खाता है और कार्य एप्लिकेशन मूड सेट करना इंट्रेंस नियम से मेल खाता है। प्रोग्रामिंग कार्य के सामान्य मामले के अलावा, टाइप थ्योरी भी सहयोगी सरणियों और समान डेटा संरचनाओं को मॉडल करने के लिए प्रथम श्रेणी के कार्य का उपयोग करती है।

श्रेणी सिद्धांत में। प्रोग्रामिंग के श्रेणी-सैद्धांतिक खाते, प्रथम श्रेणी के कार्यों की उपलब्धता बंद श्रेणी की धारणा से मेल खाती है। उदाहरण के लिए, केवल टाइप किया गया लैम्ब्डा कैलकुस कार्टेशियन बंद श्रेणी की आंतरिक भाषा से मेल खाता है।

भाषा समर्थन

एरलांग (प्रोग्रामिंग भाषा), योजना (प्रोग्रामिंग भाषा), एमएल (प्रोग्रामिंग भाषा), हास्केल (प्रोग्रामिंग भाषा), एफ शार्प (प्रोग्रामिंग भाषा)|एफ#, और स्काला (प्रोग्रामिंग भाषा) जैसी कार्यात्मक प्रोग्रामिंग भाषाएं, सभी में पहले- वर्ग कार्य। जब लिस्प (प्रोग्रामिंग लैंग्वेज), शुरुआती कार्यात्मक भाषाओं में से एक को डिजाइन किया गया था, तब प्रथम श्रेणी के कार्यों के सभी पहलुओं को ठीक से नहीं समझा गया था, जिसके परिणामस्वरूप कार्यों को गतिशील रूप से स्कॉप्ड किया गया था। बाद की स्कीम (प्रोग्रामिंग लैंग्वेज) और सामान्य लिस्प बोलियों में प्रथम श्रेणी के कार्यों को लेक्सिक रूप से स्कोप किया गया है।

पर्ल, पायथन (प्रोग्रामिंग लैंग्वेज), PHP, लुआ (प्रोग्रामिंग भाषा) , Tcl/Tk, जावास्क्रिप्ट और Io (प्रोग्रामिंग लैंग्वेज) सहित कई स्क्रिप्टिंग भाषाओं में प्रथम श्रेणी के कार्य हैं।

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

सी परिवार ने तर्कों के रूप में पारित होने वाले कार्यों और उन्हें परिणाम के रूप में वापस करने की अनुमति दी, लेकिन नेस्टेड कार्यों का समर्थन न करके किसी भी समस्या से बचा। (जीसीसी कंपाइलर उन्हें एक विस्तार के रूप में अनुमति देता है।) चूंकि रिटर्निंग कार्य की उपयोगिता मुख्य रूप से नेस्टेड कार्य को वापस करने की क्षमता में निहित है, जो शीर्ष-स्तरीय कार्य के बजाय गैर-स्थानीय चर पर कब्जा कर लिया है, इन भाषाओं को आम तौर पर पहले नहीं माना जाता है -वर्ग कार्य।

आधुनिक अनिवार्य भाषाएं अक्सर कचरा-संग्रह का समर्थन करती हैं जिससे प्रथम श्रेणी के कार्यों का कार्यान्वयन संभव हो जाता है। प्रथम श्रेणी के कार्यों को अक्सर भाषा के बाद के संशोधनों में समर्थित किया गया है, जिसमें C# 2.0 और Apple के C, C++ और Objective-C के लिए ब्लॉक एक्सटेंशन शामिल हैं। C++11 ने अनाम कार्यों और भाषा के बंद होने के लिए समर्थन जोड़ा है, लेकिन भाषा की गैर-कचरा एकत्र प्रकृति के कारण, परिणाम के रूप में लौटाए जाने वाले कार्यों में गैर-स्थानीय चर के लिए विशेष देखभाल की जानी चाहिए (नीचे देखें) ).

भाषा Higher-order functions Nested functions Non-local variables Notes
Arguments Results Named Anonymous Closures Partial application
Algol family ALGOL 60 Yes No Yes No Downwards No Have function types.
ALGOL 68 Yes Yes[8] Yes Yes Downwards[9] No
Pascal Yes No Yes No Downwards No
Ada Yes No Yes No Downwards No
Oberon Yes Non-nested only Yes No Downwards No
Delphi Yes Yes Yes 2009 2009 No
C family C Yes Yes Yes in GNU C Yes in Clang(Blocks) Yes in Clang(Blocks) No Has function pointers.
C++ Yes Yes C++11[10] C++11[11] C++11[11] C++11 Has function pointers, function objects. (Also, see below.)

Explicit partial application possible with std::bind.

C# Yes Yes 7 2.0 / 3.0 2.0 3.0 Has delegates (2.0) and lambda expressions (3.0).
Objective-C Yes Yes Using anonymous 2.0 + Blocks[12] 2.0 + Blocks No Has function pointers.
Java Yes Yes Using anonymous Java 8 Java 8 Yes Has anonymous inner classes.
Go Yes Yes Using anonymous Yes Yes Yes[13]
Limbo Yes Yes Yes Yes Yes No
Newsqueak Yes Yes Yes Yes Yes No
Rust Yes Yes Yes Yes Yes Yes[14]
Functional languages Lisp Syntax Syntax Yes Yes Common Lisp No (see below)
Scheme Yes Yes Yes Yes Yes SRFI 26[15]
Julia Yes Yes Yes Yes Yes Yes
Clojure Yes Yes Yes Yes Yes Yes
ML Yes Yes Yes Yes Yes Yes
Haskell Yes Yes Yes Yes Yes Yes
jq Yes No Yes Expressions only Downwards No
Scala Yes Yes Yes Yes Yes Yes
Erlang Yes Yes Yes Yes Yes Yes
F# Yes Yes Yes Yes Yes Yes
OCaml Yes Yes Yes Yes Yes Yes
Scripting languages Io Yes Yes Yes Yes Yes No
JavaScript Yes Yes Yes Yes Yes ECMAScript 5 Partial application possible with user-land code on ES3 [16]
Lua Yes Yes Yes Yes Yes Yes[17]
PHP Yes Yes Using anonymous 5.3 5.3 No Partial application possible with user-land code.
Perl Yes Yes 6 Yes Yes 6[18]
Python Yes Yes Yes Expressions only Yes 2.5[19] (see below)
Ruby Syntax Syntax Unscoped Yes Yes 1.9 (see below)
Other languages Fortran Yes Yes Yes No No No
Maple Yes Yes Yes Yes Yes No
Mathematica Yes Yes Yes Yes Yes No
MATLAB Yes Yes Yes Yes[20] Yes Yes Partial application possible by automatic generation of new functions.[21]
Smalltalk Yes Yes Yes Yes Yes Partial Partial application possible through library.
Swift Yes Yes Yes Yes Yes Yes
सी ++
सी ++ 11 क्लोजर कॉपी निर्माण द्वारा गैर-स्थानीय चर को संदर्भ द्वारा (उनके जीवनकाल को बढ़ाए बिना), या सी ++ 11 # रावल्यू संदर्भों द्वारा कैप्चर कर सकते हैं और कन्स्ट्रक्टर को स्थानांतरित कर सकते हैं (वैरिएबल क्लोजर के रूप में लंबे समय तक रहता है)। पहला विकल्प सुरक्षित है यदि क्लोजर लौटाया जाता है लेकिन एक प्रति की आवश्यकता होती है और मूल चर को संशोधित करने के लिए उपयोग नहीं किया जा सकता है (जो क्लोजर कहे जाने के समय मौजूद नहीं हो सकता है)। दूसरा विकल्प संभावित रूप से एक महंगी प्रति से बचता है और मूल चर को संशोधित करने की अनुमति देता है लेकिन बंद होने की स्थिति में असुरक्षित है (झूलते संदर्भ देखें)। तीसरा विकल्प सुरक्षित है अगर क्लोजर लौटाया जाता है और कॉपी की आवश्यकता नहीं होती है लेकिन मूल चर को संशोधित करने के लिए भी इसका उपयोग नहीं किया जा सकता है।
जावा
जावा 8 क्लोजर केवल अंतिम या प्रभावी रूप से अंतिम गैर-स्थानीय चर पर कब्जा कर सकते हैं। जावा के कार्य प्रकारों को कक्षाओं के रूप में दर्शाया जाता है। अनाम कार्य संदर्भ से अनुमानित प्रकार लेते हैं। विधि संदर्भ सीमित हैं। अधिक जानकारी के लिए देखें Anonymous function § Java limitations.
तुतलाना
लेक्सिकली स्कोप्ड लिस्प वेरिएंट क्लोजर का समर्थन करता है। डायनामिक रूप से स्कोप किए गए वेरिएंट क्लोजर का समर्थन नहीं करते हैं या क्लोजर बनाने के लिए एक विशेष निर्माण की आवश्यकता होती है।[22]
सामान्य लिस्प में, कार्य नेमस्पेस में कार्य के पहचानकर्ता को प्रथम श्रेणी के मान के संदर्भ के रूप में उपयोग नहीं किया जा सकता है। विशेष संचालिका function कार्य को मान के रूप में पुनर्प्राप्त करने के लिए उपयोग किया जाना चाहिए: (function foo) एक कार्य ऑब्जेक्ट का मूल्यांकन करता है। #'foo आशुलिपि संकेतन के रूप में मौजूद है। इस तरह के कार्य ऑब्जेक्ट को लागू करने के लिए, इसका उपयोग करना चाहिए funcall कार्य  : (funcall #'foo bar baz).
अजगर
स्पष्ट आंशिक आवेदन के साथ functools.partial संस्करण 2.5 के बाद से, और operator.methodcaller संस्करण 2.6 के बाद से।
माणिक
रूबी (जो वास्तव में एक विधि है) में नियमित कार्य के पहचानकर्ता को मूल्य या पारित के रूप में उपयोग नहीं किया जा सकता है। इसे पहले एक में पुनर्प्राप्त किया जाना चाहिए Method या Proc प्रथम श्रेणी के डेटा के रूप में उपयोग की जाने वाली वस्तु। ऐसे कार्य ऑब्जेक्ट को कॉल करने का सिंटैक्स नियमित तरीकों को कॉल करने से भिन्न होता है।
नेस्टेड विधि परिभाषाएँ वास्तव में स्कोप को नेस्ट नहीं करती हैं।
स्पष्ट करी के साथ [1].

यह भी देखें

टिप्पणियाँ

  1. Abelson, Harold; Sussman, Gerald Jay (1984). कंप्यूटर प्रोग्राम की संरचना और व्याख्या. MIT Press. Formulating Abstractions with Higher-Order Procedures. ISBN 0-262-01077-1.
  2. Programming language pragmatics, by Michael Lee Scott, section 11.2 "Functional Programming".
  3. Roberto Ierusalimschy; Luiz Henrique de Figueiredo; Waldemar Celes (2005). "The Implementation of Lua 5.0". Journal of Universal Computer Science. 11 (7): 1159–1176. doi:10.3217/jucs-011-07-1159.
  4. 4.0 4.1 Burstall, Rod; Strachey, Christopher (2000). "प्रोग्रामिंग भाषाओं को समझना" (PDF). Higher-Order and Symbolic Computation. 13 (52): 11–49. doi:10.1023/A:1010052305354. S2CID 1989590. Archived from the original on February 16, 2010.{{cite journal}}: CS1 maint: bot: original URL status unknown (link) (also on 2010-02-16
  5. Joel Moses. "The Function of FUNCTION in LISP, or Why the FUNARG Problem Should be Called the Environment Problem". MIT AI Memo 199, 1970.
  6. "If you try to call the nested function through its address after the containing function has exited, all hell will break loose." (GNU Compiler Collection: Nested Functions)
  7. Andrew W. Appel (1995). "Intensional Equality ;=) for Continuations".
  8. Tanenbaum, A.S. (1977). "A comparison of PASCAL and Algol 68". The Computer Journal. 21 (4): 319. doi:10.1093/comjnl/21.4.316.
  9. "The History of Python: Origins of Python's "Functional" Features". 21 April 2009.
  10. Nested functions using lambdas/closures
  11. 11.0 11.1 Doc No. 1968: V Samko; J Willcock, J Järvi, D Gregor, A Lumsdaine (February 26, 2006) Lambda expressions and closures for C++
  12. "Mac Dev Center: Blocks Programming Topics: Introduction". Archived from the original on 2009-08-31.
  13. "2 examples in Go that you can have partial application".
  14. "partial_application". Docs.rs. Retrieved 2020-11-03.
  15. "SRFI 26: Notation for Specializing Parameters without Currying".
  16. "John Resig - Partial Application in JavaScript".
  17. Katz, Ian (July 23, 2010). "Lua Code for Curry (Currying Functions)". Archived from the original on 2018-11-06.
  18. "Blog | Perlgeek.de :: Currying".
  19. "What's New in Python 2.5 — Python 3.10.0 documentation".
  20. "Anonymous Functions - MATLAB & Simulink - MathWorks United Kingdom".
  21. Partial Function Evaluation in MATLAB
  22. Closures in ZetaLisp Archived 2012-03-19 at the Wayback Machine


संदर्भ


बाहरी संबंध