क्लोजर (कंप्यूटर प्रोग्रामिंग): Difference between revisions

From Vigyanwiki
No edit summary
No edit summary
 
(14 intermediate revisions by 3 users not shown)
Line 3: Line 3:
{{distinguish|text=प्रोग्रामिंग भाषा [[क्लोजर]]}}
{{distinguish|text=प्रोग्रामिंग भाषा [[क्लोजर]]}}


[[प्रोग्रामिंग भाषा|प्रोग्रामिंग भाषाओं]] में, '''क्लोजर''', '''लेक्सिकल क्लोजर''' या '''फंक्शन क्लोजर''' भी प्रथम श्रेणी के कार्यों के साथ भाषा में [[लेक्सिकली स्कोप्ड]] [[नाम बंधन]] को प्रयुक्त करने की तकनीक है। क्रियात्मक रूप से [[परिचालन शब्दार्थ]], क्लोजर [[रिकॉर्ड (कंप्यूटर विज्ञान)]] है। जो [[समारोह (कंप्यूटर विज्ञान)|फ़ंक्शन (कंप्यूटर विज्ञान)]] को पर्यावरण के साथ संग्रहित करता है।<ref>Sussman and Steele. "Scheme: An interpreter for extended lambda calculus". "... a data structure containing a lambda expression, and an environment to be used when that lambda expression is applied to arguments." ([[s:Page:Scheme - An interpreter for extended lambda calculus.djvu/22|Wikisource]])</ref> चूँकि पर्यावरण मानचित्रण है। जो फ़ंक्शन के प्रत्येक [[मुक्त चर]] को जोड़ता है। (चर जो स्थानीय रूप से उपयोग किए जाते हैं। किन्तु संलग्न चक्र में परिभाषित होते हैं।) अतः [[मूल्य (कंप्यूटर विज्ञान)]] या [[संदर्भ (कंप्यूटर विज्ञान)]] के साथ जिसका नाम बंधन होने पर नाम बाध्य बनाया गया था।{{efn|These names most frequently refer to values, mutable variables, or functions, but can also be other entities such as constants, types, classes, or labels.}} सामान्यतः साधारण फ़ंक्शन के विपरीत, क्लोजर फ़ंक्शन को कैप्चर किए गए चरों को उनके मूल्यों या संदर्भों की क्लोजर प्रतियों के माध्यम से प्रवेश करने की अनुमति देता है, तथापि जब फ़ंक्शन को उनके चक्र से बाहर वर्णित किया जाता है।
[[प्रोग्रामिंग भाषा|प्रोग्रामिंग भाषाओं]] में, '''क्लोजर''', '''शाब्दिक क्लोजर''' या '''फंक्शन क्लोजर''' भी प्रथम श्रेणी के फंक्शन के साथ भाषा में [[लेक्सिकली स्कोप्ड|शाब्दिकी विस्तार]] [[नाम बंधन]] को प्रयुक्त करने की विधि है। क्रियात्मक रूप से [[परिचालन शब्दार्थ]], क्लोजर [[रिकॉर्ड (कंप्यूटर विज्ञान)]] होता है। जो [[समारोह (कंप्यूटर विज्ञान)|फंक्शन (कंप्यूटर विज्ञान)]] को पर्यावरण के साथ संग्रहित करता है।<ref>Sussman and Steele. "Scheme: An interpreter for extended lambda calculus". "... a data structure containing a lambda expression, and an environment to be used when that lambda expression is applied to arguments." ([[s:Page:Scheme - An interpreter for extended lambda calculus.djvu/22|Wikisource]])</ref> चूँकि पर्यावरण मानचित्रण है। जो फंक्शन के प्रत्येक [[मुक्त चर]] को जोड़ता है। (चर जो स्थानीय रूप से उपयोग किए जाते हैं। किन्तु संलग्न क्षेत्र में परिभाषित होते हैं।) अतः [[मूल्य (कंप्यूटर विज्ञान)]] या [[संदर्भ (कंप्यूटर विज्ञान)]] के साथ जिसका नाम बंधन होने पर नाम बाध्य बनाया गया था।{{efn|These names most frequently refer to values, mutable variables, or functions, but can also be other entities such as constants, types, classes, or labels.}} सामान्यतः साधारण फंक्शन के विपरीत, क्लोजर फंक्शन को अधिकृत किए गए चरों को उनके मूल्यों या संदर्भों की क्लोजर प्रतियों के माध्यम से प्रवेश करने की अनुमति देता है। तथापि जब फंक्शन को उनके क्षेत्र से बाहर वर्णित किया जाता है।
[[Category: Templates Vigyan Ready]]
 
== इतिहास और व्युत्पत्त ==
== इतिहास और व्युत्पत्त ==
क्लोजर की अवधारणा को सन्न 1960 के दशक में λ-कैलकुलस में भावों के यांत्रिक मूल्यांकन के लिए विकसित किया गया था और प्रथम बार सन्न 1970 में पूर्ण प्रकार से आरपीएल प्रोग्रामिंग भाषा में भाषा सुविधा के रूप में प्रयुक्त किया गया था। जिससे कि लेक्सिक रूप से प्रथम श्रेणी के कार्यों का समर्थन किया जा सकता है।<ref name=dat2012>[[David A. Turner]] (2012). [http://www.cs.kent.ac.uk/people/staff/dat/tfp12/tfp12.pdf "Some History of Functional Programming Languages"]. Trends in Functional Programming '12. Section 2, note 8 contains the claim about M-expressions.</ref>
क्लोजर की अवधारणा को सन्न 1960 के दशक में λ-कैलकुलस में भावों के यांत्रिक मूल्यांकन के लिए विकसित किया गया था और प्रथम बार सन्न 1970 में पूर्ण प्रकार से आरपीएल प्रोग्रामिंग भाषा में भाषा सुविधा के रूप में प्रयुक्त किया गया था। जिससे कि शाब्दिक रूप से प्रथम श्रेणी के फंक्शन का समर्थन किया जा सकता था।<ref name=dat2012>[[David A. Turner]] (2012). [http://www.cs.kent.ac.uk/people/staff/dat/tfp12/tfp12.pdf "Some History of Functional Programming Languages"]. Trends in Functional Programming '12. Section 2, note 8 contains the claim about M-expressions.</ref>


पीटर जे. लैंडिन ने सन्न 1964 में टर्म क्लोजर को पर्यावरण भाग और नियंत्रण भाग के रूप में परिभाषित किया था। जैसा कि अभिव्यक्ति के मूल्यांकन के लिए उनकी एसईसीडी मशीन द्वारा उपयोग किया जाता है।<ref name="landin">{{citation
पीटर जे. लैंडिन ने सन्न 1964 में सीमा क्लोजर को पर्यावरण भाग और नियंत्रण भाग के रूप में परिभाषित किया था। जैसा कि अभिव्यक्ति के मूल्यांकन के लिए उनकी एसईसीडी मशीन द्वारा उपयोग किया जाता है।<ref name="landin">{{citation
| author = P. J. Landin | year = 1964 | title = The mechanical evaluation of expressions | author-link = Peter J. Landin }}</ref> [[जोएल मूसा|जोएल मोसेस]] ने लैम्ब्डा एक्सप्रेशन को संदर्भित करने के लिए क्लोजर शब्द की शुरुआत करने का श्रेय लैंडिन को दिया है। जिसके ओपन बाइंडिंग (फ्री वेरिएबल्स) को लेक्सिकल वातावरण द्वारा (या बाउंड इन) बंद कर दिया गया है। जिसके परिणामस्वरूप क्लोज्ड एक्सप्रेशन या क्लोजर होता है।<ref>{{citation
| author = P. J. Landin | year = 1964 | title = The mechanical evaluation of expressions | author-link = Peter J. Landin }}</ref> [[जोएल मूसा|जोएल मोसेस]] ने लैम्ब्डा अभिव्यक्ति को संदर्भित करने के लिए क्लोजर शब्द की शुरुआत करने का श्रेय लैंडिन को दिया है। जिसके खुला बंधन (नि: शुल्क चरों) को शाब्दिक वातावरण द्वारा (या आंतरिक) क्लोजर कर दिया गया है। जिसके परिणामस्वरूप क्लोजर अभिव्यक्ति या क्लोजर होता है।<ref>{{citation
| author = Joel Moses |date=June 1970 | title = The Function of FUNCTION in LISP, or Why the FUNARG Problem Should Be Called the Environment Problem | id = [[AI Memo]] 199| quote = A useful metaphor for the difference between FUNCTION and QUOTE in LISP is to think of QUOTE as a porous or an open covering of the function since free variables escape to the current environment. FUNCTION acts as a closed or nonporous covering (hence the term "closure" used by Landin). Thus we talk of "open" Lambda expressions (functions in LISP are usually Lambda expressions) and "closed" Lambda expressions. [...] My interest in the environment problem began while Landin, who had a deep understanding of the problem, visited MIT during 1966–67. I then realized the correspondence between the FUNARG lists which are the results of the evaluation of "closed" Lambda expressions in [[LISP 1.5|LISP]] and [[ISWIM]]'s Lambda Closures.|hdl=1721.1/5854 |author-link=Joel Moses }}</ref><ref>{{cite book| author = Åke Wikström| year = 1987| title = Functional Programming using Standard ML| isbn = 0-13-331968-7| quote = The reason it is called a "closure" is that an expression containing free variables is called an "open" expression, and by associating to it the bindings of its free variables, you close it.| author-link = Åke Wikström}}</ref> इस प्रयोग को बाद में [[गेराल्ड जे सुस्मान]] और गाइ एल. स्टील, जूनियर द्वारा अपनाया गया, जब उन्होंने सन्न 1975 में योजना (प्रोग्रामिंग भाषा) को परिभाषित किया था।<ref>{{citation| author = [[Gerald Jay Sussman]] and [[Guy L. Steele, Jr.]]|date=December 1975| title = Scheme: An Interpreter for the Extended Lambda Calculus| id = [[AI Memo]] 349}}</ref> अतः [[लिस्प (प्रोग्रामिंग भाषा)]] का लेक्सिकली स्कोप्ड वेरिएंट और व्यापक हो गया है।
| author = Joel Moses |date=June 1970 | title = The Function of FUNCTION in LISP, or Why the FUNARG Problem Should Be Called the Environment Problem | id = [[AI Memo]] 199| quote = A useful metaphor for the difference between FUNCTION and QUOTE in LISP is to think of QUOTE as a porous or an open covering of the function since free variables escape to the current environment. FUNCTION acts as a closed or nonporous covering (hence the term "closure" used by Landin). Thus we talk of "open" Lambda expressions (functions in LISP are usually Lambda expressions) and "closed" Lambda expressions. [...] My interest in the environment problem began while Landin, who had a deep understanding of the problem, visited MIT during 1966–67. I then realized the correspondence between the FUNARG lists which are the results of the evaluation of "closed" Lambda expressions in [[LISP 1.5|LISP]] and [[ISWIM]]'s Lambda Closures.|hdl=1721.1/5854 |author-link=Joel Moses }}</ref><ref>{{cite book| author = Åke Wikström| year = 1987| title = Functional Programming using Standard ML| isbn = 0-13-331968-7| quote = The reason it is called a "closure" is that an expression containing free variables is called an "open" expression, and by associating to it the bindings of its free variables, you close it.| author-link = Åke Wikström}}</ref> इस प्रयोग को पश्चात् में [[गेराल्ड जे सुस्मान]] और गाइ एल. स्टील, जूनियर द्वारा अपनाया गया था। जब उन्होंने सन्न 1975 में योजना (प्रोग्रामिंग भाषा) को परिभाषित किया था।<ref>{{citation| author = [[Gerald Jay Sussman]] and [[Guy L. Steele, Jr.]]|date=December 1975| title = Scheme: An Interpreter for the Extended Lambda Calculus| id = [[AI Memo]] 349}}</ref> अतः [[लिस्प (प्रोग्रामिंग भाषा)]] का शाब्दिकी विस्तार रूपांतर और व्यापक हो गया है।


सुस्मान और [[हेरोल्ड एबेलसन]] भी सन्न 1980 के दशक में दूसरे, असंबंधित अर्थ के साथ क्लोजर शब्द का उपयोग करते हैं। चूँकि ऑपरेटर की संपत्ति जो [[डेटा संरचना]] में डेटा जोड़ती है और स्थिर डेटा संरचनाओं को भी जोड़ने में सक्षम होती है। अतः यह शब्द का प्रयोग कंप्यूटर विज्ञान में पूर्व उपयोग के अतिरिक्त क्लोजर (गणित) से आता है। जिसे लेखक शब्दावली में इस ओवरलैप को "दुर्भाग्यपूर्ण" मानते हैं।<ref>{{cite book |last1=Abelson |first1=Harold |last2=Sussman |first2=Gerald Jay |last3=Sussman |first3=Julie |date=1996 |title=Structure and Interpretation of Computer Programs |url=https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html |location=Cambridge, MA |publisher=MIT Press |page=98–99 |isbn=0262510871}}</ref>
सुस्मान और [[हेरोल्ड एबेलसन]] भी सन्न 1980 के दशक में दूसरे असंबंधित अर्थ के साथ क्लोजर शब्द का उपयोग करते हैं। चूँकि ऑपरेटर की संपत्ति जो [[डेटा संरचना]] में डेटा जोड़ती है और स्थिर डेटा संरचनाओं को भी जोड़ने में सक्षम होती है। अतः यह शब्द का प्रयोग कंप्यूटर विज्ञान में पूर्व उपयोग के अतिरिक्त क्लोजर (गणित) से आता है। जिसे लेखक शब्दावली में इस ओवरलैप को "दुर्भाग्यपूर्ण" मानते हैं।<ref>{{cite book |last1=Abelson |first1=Harold |last2=Sussman |first2=Gerald Jay |last3=Sussman |first3=Julie |date=1996 |title=Structure and Interpretation of Computer Programs |url=https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html |location=Cambridge, MA |publisher=MIT Press |page=98–99 |isbn=0262510871}}</ref>
== अनाम कार्य ==
== अनाम कार्य ==
{{further|अनाम समारोह}}
{{further|अनाम समारोह}}


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


उदाहरण के लिए, निम्नलिखित [[पायथन (प्रोग्रामिंग भाषा)]] कोड में:
उदाहरण के लिए, निम्नलिखित [[पायथन (प्रोग्रामिंग भाषा)]] कोड में,
<वाक्यविन्यास लैंग = अजगर>
   def f(x):
डेफ एफ (एक्स):
   डेफ जी (वाई):
  रिटर्न एक्स + वाई
  रिटर्न जी # रिटर्न क्लोजर।


डीईएफ़ एच (एक्स):
    def g(y):
  रिटर्न लैम्ब्डा वाई: एक्स + वाई # क्लोजर लौटाएं।
        return x + y
    return g  # Return a closure.
def h(x):
    return lambda y: x + y  # Return a closure.
# Assigning specific closures to variables.
a = f(1)
b = h(1)
# Using the closures stored in variables.
assert a(5) == 6
assert b(5) == 6
# Using closures without binding them to variables first.
assert f(1)(5) == 6  # f(1) is the closure.


# वेरिएबल्स को विशिष्ट क्लोजर असाइन करना।
assert h(1)(5) == 6  # h(1) is the closure.
ए = एफ (1)
# प्रथम चर से आबद्ध किए बिना क्लोजर का उपयोग करता है।
बी = एच (1)
सामान्यतः <code>a</code> और <code>b</code> के मान क्लोजर होते है। जो दोनों स्थितियों में स्थिर फंक्शन को संलग्न फंक्शन से मुक्त चर के साथ वापस करके उत्पादित किया जाता है। जिससे कि मुक्त चर संलग्न फंक्शन के पैरामीटर <code>x</code> के मान से जुड़ जाता है। चूँकि <code>a</code> और <code>b</code> में क्लोजर कार्यात्मक रूप से समान हैं। कार्यान्वयन में एकमात्र अंतर यह है कि प्रथम स्थितियों में हमने नाम <code>g</code> के साथ स्थिर फंक्शन का उपयोग नाम के साथ किया था। (अज्ञात फंक्शन बनाने के लिए पाइथन संकेत शब्द <code>lambda</code> का उपयोग करके) उन्हें परिभाषित करने में यदि कोई मूल नाम प्रयुक्त होता है, वह अप्रासंगिक है।


# वेरिएबल्स में संग्रह किए गए क्लोजर का उपयोग करना।
क्लोजर किसी भी अन्य मान की भांति वह मान है। इसके चर को नियुक्त करने की आवश्यकता नहीं है और इसके अतिरिक्त इसे सीधे उपयोग किया जा सकता है। जैसा कि उदाहरण की अंतिम दो पंक्तियों में दिखाया गया है। इस उपयोग को अनाम क्लोजर माना जा सकता है।
ए (5) == 6 पर जोर दें
जोर बी (5) == 6


# पहले वेरिएबल से बाइंड किए बिना क्लोजर का उपयोग करना।
चूँकि स्थिर फंक्शन परिभाषाएं स्वयं क्लोजर नहीं हैं। उनके समीप मुक्त चर है। जो अभी तक बाध्य नहीं है। अतः केवल संलग्न फंक्शन का मूल्यांकन पैरामीटर के मान के साथ किया जाता है। स्थिर फंक्शन सीमित का मुक्त चर होता है। जो क्लोजर बनाता है। जिसे पश्चात् में संलग्न फंक्शन से लौटाया जाता है।
जोर दें f(1)(5) == 6 # f(1) क्लोजर है।
जोर एच (1) (5) == 6 # एच (1) बंद है।
</वाक्यविन्यास हाइलाइट>
के मूल्य <code>a</code> और <code>b</code> क्लोजर हैं, दोनों स्थितियों में नेस्टेड फ़ंक्शन को एन्क्लोजिंग फ़ंक्शन से मुक्त चर के साथ लौटाकर उत्पादित किया जाता है, जिससे कि मुक्त चर पैरामीटर के मान से जुड़ा हो <code>x</code> संलग्न समारोह का। में बंद हैं <code>a</code> और <code>b</code> कार्यात्मक रूप से समान हैं। कार्यान्वयन में एकमात्र अंतर यह है कि पहले स्थितियों में हमने नेस्टेड फ़ंक्शन का उपयोग नाम के साथ किया था, <code>g</code>, जबकि दूसरे स्थितियों में हमने अनाम नेस्टेड फ़ंक्शन (Python कीवर्ड का उपयोग करके) का उपयोग किया <code>lambda</code> अज्ञात फ़ंक्शन बनाने के लिए)। उन्हें परिभाषित करने में प्रयुक्त मूल नाम, यदि कोई हो, अप्रासंगिक है।


क्लोजर किसी भी अन्य वैल्यू की तरह वैल्यू है। इसे वेरिएबल को असाइन करने की आवश्यकता नहीं है और इसके अतिरिक्त इसे सीधे उपयोग किया जा सकता है, जैसा कि उदाहरण की अंतिम दो पंक्तियों में दिखाया गया है। इस उपयोग को अनाम क्लोजर माना जा सकता है।
अंत में, गैर-स्थानीय चर के क्षेत्र से बाहर होने पर क्लोजर केवल मुक्त चर वाले फंक्शन से प्रथक होता है। अन्यथा परिभाषित वातावरण और निष्पादन वातावरण से मेल खाते हैं और इन्हें प्रथक करने के लिए कुछ भी नहीं है। (स्थैतिक और गतिशील बाध्यकारी को प्रथक नहीं किया जा सकता है। जिससे कि नाम समान मानों को हल करते हैं।) उदाहरण के लिए, नीचे दिए गए प्रोग्राम में, मुक्त चर <code>x</code> (वैश्विक सीमा के साथ गैर-स्थानीय चर <code>x</code> के लिए बाध्य) वाले कार्यो को उसी वातावरण में निष्पादित किया जाता हैं। जहाँ <code>x</code> को परिभाषित किया गया है। अतः यह सारहीन है कि क्या ये वास्तव में क्लोजर हैं।
nums = [1, 2, 3]
def f(y):
    return x + y
map(f, nums)


नेस्टेड फ़ंक्शन परिभाषाएं स्वयं क्लोजर नहीं हैं: उनके पास फ्री वेरिएबल है जो अभी तक बाध्य नहीं है। केवल बार एनक्लोजिंग फ़ंक्शन का मूल्यांकन पैरामीटर के मान के साथ किया जाता है, नेस्टेड फ़ंक्शन बाउंड का फ्री वेरिएबल होता है, जो क्लोजर बनाता है, जिसे बाद में एनक्लोजिंग फ़ंक्शन से लौटाया जाता है।
map(lambda y: x + y, nums)
यह अधिकांशतः फंक्शन वापसी द्वारा प्राप्त किया जाता है। चूँकि फंक्शन को गैर-स्थानीय चर के क्षेत्र में परिभाषित किया जाना चाहिए। इस स्थितियों में सामान्यतः इसका क्षेत्र <code>g</code> छोटा होता है।


अंत में, गैर-स्थानीय चर के चक्र से बाहर होने पर क्लोजर केवल मुक्त चर वाले फ़ंक्शन से अलग होता है, अन्यथा परिभाषित वातावरण और निष्पादन वातावरण मेल खाते हैं और इन्हें अलग करने के लिए कुछ भी नहीं है (स्थैतिक और गतिशील बाध्यकारी को अलग नहीं किया जा सकता है क्योंकि नाम समान मानों को हल करते हैं)। उदाहरण के लिए, नीचे दिए गए प्रोग्राम में, फ्री वेरिएबल के साथ कार्य करता है <code>x</code> (गैर-स्थानीय चर के लिए बाध्य <code>x</code> वैश्विक चक्र के साथ) उसी वातावरण में क्रियान्वित किए जाते हैं जहाँ <code>x</code> परिभाषित किया गया है, इसलिए यह सारहीन है कि क्या ये वास्तव में बंद हैं:
यह [[चर छायांकन]] (जो गैर-स्थानीय चर के क्षेत्र को कम करता है।) द्वारा भी प्राप्त किया जा सकता है। चूंकि व्यवहार में यह कम साधारण है। चूंकि यह कम उपयोगी है और छायांकन को हतोत्साहित किया जाता है। इस उदाहरण में <code>f</code> क्लोजर के रूप में देखा जा सकता है। जिससे कि <code>f</code> के शरीर में <code>x</code> वैश्विक नाम स्थान में <code>x</code> के लिए बाध्य है न कि <code>x</code> स्थानीय के लिए <code>g</code> होता है।
<वाक्यविन्यास लैंग = अजगर>
def f(y):
एक्स = 1
    return x + y
अंक = [1, 2, 3]
def g(z):
    x = 1 # local x shadows global x
    return f(z)


डेफ एफ (वाई):
  रिटर्न एक्स + वाई


नक्शा (एफ, अंक)
g(1) # evaluates to 1, not 2
नक्शा (लैम्ब्डा वाई: एक्स + वाई, अंक)
</वाक्यविन्यास हाइलाइट>
यह अधिकांशतः फ़ंक्शन रिटर्न द्वारा हासिल किया जाता है, क्योंकि फ़ंक्शन को गैर-स्थानीय चर के चक्र में परिभाषित किया जाना चाहिए, इस स्थितियों में सामान्यतः इसका दायरा छोटा होगा।


यह [[चर छायांकन]] (जो गैर-स्थानीय चर के चक्र को कम करता है) द्वारा भी प्राप्त किया जा सकता है, चूंकि व्यवहार में यह कम आम है, क्योंकि यह कम उपयोगी है और शैडोइंग को हतोत्साहित किया जाता है। इस उदाहरण में <code>f</code> बंद होने के रूप में देखा जा सकता है क्योंकि <code>x</code> के शरीर में <code>f</code> के लिए बाध्य है <code>x</code> वैश्विक नामस्थान में, नहीं <code>x</code> स्थानीय के लिए <code>g</code>:
== अनुप्रयोग ==
<वाक्यविन्यास लैंग = अजगर>
क्लोजर का उपयोग उन भाषाओं से जुड़ा हुआ है। जहां कार्य [[प्रथम श्रेणी की वस्तु|प्रथम श्रेणी की वस्तुएं]] हैं। जिसमें उच्च-क्रम के फंक्शन के परिणाम के रूप में फंक्शन को वापस किया जा सकता है या अन्य फंक्शन कॉलों के लिए तर्क के रूप में पारित किया जा सकता है। यदि मुक्त चर वाले कार्य प्रथम श्रेणी के हैं। तब वापस लौटने से क्लोजर हो जाता है। इसमें लिस्प (प्रोग्रामिंग भाषा) और [[एमएल (प्रोग्रामिंग भाषा)]], जैसी [[कार्यात्मक प्रोग्रामिंग भाषाएं|कार्यात्मक प्रोग्रामिंग भाषाओं]] के साथ-साथ जूलिया, पायथन और रस्ट जैसी अनेक आधुनिक, बहु-प्रतिमान भाषाएं सम्मिलित हैं। [[कॉलबैक (कंप्यूटर प्रोग्रामिंग)]] के साथ क्लोजर का भी अधिकांशतः उपयोग किया जाता है। विशेष रूप से [[आयोजन प्रबंधकर्ता]] के लिए, जैसे कि [[जावास्क्रिप्ट|जावालिपि]] में, जहां उनका उपयोग [[गतिशील वेब पेज]] के साथ बातचीत के लिए किया जाता है।
एक्स = 0


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


डेफ जी (जेड):
=== प्रथम श्रेणी के कार्य ===
  x = 1 # स्थानीय x छाया वैश्विक x
{{further|प्रथम श्रेणी समारोह}}
  रिटर्न एफ (जेड)


g(1) # 1 का मूल्यांकन करता है, 2 का नहीं
क्लोजर सामान्यतः प्रथम श्रेणी के फंक्शन के साथ भाषाओं में दिखाई देते हैं। चूँकि दूसरे शब्दों में, ऐसी भाषाएं फंक्शन को तर्कों के रूप में पारित करने में सक्षम बनाती हैं। अतः फंक्शन कॉल से वापस आती हैं और चर नामों से बंधी होती हैं। साधारण रूप से जैसे शृंखला के प्रकार और पूर्णांक होते है। उदाहरण के लिए, निम्नलिखित योजना (प्रोग्रामिंग भाषा) फंक्शन पर विचार कर सकते है।
</वाक्यविन्यास हाइलाइट>
; विक्रय गई कम से कम सीमा प्रतियों वाली सभी पुस्तकों की सूची लौटाएं।
(परिभाषित करें (सर्वाधिक विक्रय होने वाली पुस्तकों की सीमा)
; Return a list of all books with at least THRESHOLD copies sold.
(define (best-selling-books threshold)
  (filter
    (lambda (book)
      (>= (book-sales book) threshold))
  book-list))
इस उदाहरण में, [[लैम्ब्डा (प्रोग्रामिंग)]]  <code>(lambda (book) (>= (book-sales book) threshold))</code> <code>best-selling-books</code>फंक्शन के अंदर दिखाई देता है जब लैम्ब्डा अभिव्यक्ति का मूल्यांकन किया जाता है। तब योजना लैम्ब्डा अभिव्यक्ति के लिए कोड और संदर्भ से मिलकर <code>threshold</code>चर क्लोजर बनाती है। जो लैम्ब्डा अभिव्यक्ति के अंदर मुक्त चर है।


== अनुप्रयोग ==
इसके पश्चात् क्लोजर को <code>filter</code> फंक्शन में भेज दिया जाता है। जो यह निर्धारित करने के लिए बार-बार कॉल करता है कि कौन सी पुस्तकें परिणाम सूची में जोड़ी जानी हैं और कौन सी छोड़ी जानी हैं। चूंकि क्लोजर में <code>threshold</code>का संदर्भ होता है। अतः अधिकांशतः जब फ़िल्टर इसे कॉल करता है तब वह उस चर का उपयोग कर सकता है। फंक्शन <code>filter</code> पूर्ण प्रकार से भिन्न फ़ाइल में परिभाषित किया जा सकता है।
क्लोजर का उपयोग उन भाषाओं से जुड़ा हुआ है जहां कार्य [[प्रथम श्रेणी की वस्तु]]एं हैं, जिसमें उच्च-क्रम के कार्यों के परिणाम के रूप में कार्यों को वापस किया जा सकता है, या अन्य फ़ंक्शन कॉलों के लिए तर्क के रूप में पारित किया जा सकता है; यदि मुक्त चर वाले कार्य प्रथम श्रेणी के हैं, तो वापस लौटने से बंद हो जाता है। इसमें [[कार्यात्मक प्रोग्रामिंग भाषाएं]] जैसे लिस्प (प्रोग्रामिंग भाषा) और [[एमएल (प्रोग्रामिंग भाषा)]], साथ ही साथ कई आधुनिक, बहु-प्रतिमान भाषाएं सम्मिलित हैं, जैसे
[[जूलिया (प्रोग्रामिंग भाषा)]],
पायथन (प्रोग्रामिंग भाषा) और
[[जंग (प्रोग्रामिंग भाषा)]]।
[[कॉलबैक (कंप्यूटर प्रोग्रामिंग)]] के साथ क्लोजर का भी अधिकांशतः उपयोग किया जाता है, विशेष रूप से [[आयोजन प्रबंधकर्ता]] के लिए, जैसे कि [[जावास्क्रिप्ट]] में, जहां उनका उपयोग [[गतिशील वेब पेज]] के साथ बातचीत के लिए किया जाता है।


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


=== प्रथम श्रेणी के कार्य ===
विक्रय की गई कम से कम 'दहलीज' प्रतियों वाली सभी पुस्तकों की सूची को वापस किया जाता है।
{{further|प्रथम श्रेणी समारोह}}


क्लोजर सामान्यतः प्रथम श्रेणी के ऑब्जेक्ट वाली भाषाओं में दिखाई देते हैं। प्रथम श्रेणी के कार्य-दूसरे शब्दों में, ऐसी भाषाएं फ़ंक्शन को तर्कों के रूप में पारित करने में सक्षम बनाती हैं, फ़ंक्शन कॉल से वापस आती हैं, चर नामों से बंधी होती हैं, आदि, सरल प्रकार जैसे स्ट्रिंग्स की तरह और पूर्णांक। उदाहरण के लिए, निम्नलिखित योजना (प्रोग्रामिंग भाषा) फ़ंक्शन पर विचार करें:
सबसे अधिक विक्रय होने वाली पुस्तकें (सीमा) कार्य करता है। {
<वाक्यविन्यास लैंग = योजना>
   // Return a list of all books with at least 'threshold' copies sold.
; बेची गई कम से कम थ्रेशोल्ड प्रतियों वाली सभी पुस्तकों की सूची लौटाएं।
(परिभाषित करें (सर्वाधिक बिकने वाली पुस्तकों की सीमा)
   (फ़िल्टर
  (लैम्ब्डा (पुस्तक)
  (>= (पुस्तक-बिक्री बही) सीमा))
  पुस्तक सूची))
</वाक्यविन्यास हाइलाइट>


इस उदाहरण में, [[लैम्ब्डा (प्रोग्रामिंग)]] <code>(lambda (book) (>= (book-sales book) threshold))</code> समारोह में प्रकट होता है <code>best-selling-books</code>. जब लैम्ब्डा अभिव्यक्ति का मूल्यांकन किया जाता है, तो योजना लैम्ब्डा अभिव्यक्ति के लिए कोड और संदर्भ के लिए क्लोजर बनाती है <code>threshold</code> वेरिएबल, जो लैम्ब्डा एक्सप्रेशन के अंदर फ्री वेरिएबल है।
function bestSellingBooks(threshold) {
  return bookList.filter(
      function (book) { return book.sales >= threshold; }
    );
}
<code>lambda</code>के अतिरिक्त <code>function</code> संपर्क का प्रयोग यहा किया जाता है और वैश्विक <code>filter</code> फंक्शन के अतिरिक्त <code>Array.filter</code> विधि<ref>{{cite web | url = https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/filter | title = array.filter | work = Mozilla Developer Center | date = 10 January 2010 | access-date = 2010-02-09}}</ref> का उपयोग किया जाता है। किन्तु संरचना और कोड का प्रभाव समान होता है। फंक्शन क्लोजर बना सकता है और इसे वापस कर सकता है। जैसा कि निम्नलिखित उदाहरण में है।


इसके बाद क्लोजर को पास कर दिया जाता है <code>filter</code> फ़ंक्शन, जो यह निर्धारित करने के लिए बार-बार कॉल करता है कि परिणाम सूची में कौन सी पुस्तकें जोड़ी जानी हैं और कौन सी छोड़ी जानी हैं। क्योंकि बंद करने का ही संदर्भ है <code>threshold</code>, यह हर बार उस चर का उपयोग कर सकता है <code>filter</code> इसे कहते हैं। कार्यक्रम <code>filter</code> स्वयं को पूरी तरह से अलग फ़ाइल में परिभाषित किया जा सकता है।
// फंक्शन वापस करता है जो एफ के व्युत्पन्न का अनुमान लगाता है।


यहाँ उसी उदाहरण को जावास्क्रिप्ट में फिर से लिखा गया है, क्लोजर के लिए समर्थन के साथ अन्य लोकप्रिय भाषा:
// डीएक्स के अंतराल का उपयोग करता है। जो उचित रूप से छोटा होना चाहिए।
<वाक्यविन्यास लैंग = जावास्क्रिप्ट>
// बेची गई कम से कम 'दहलीज' प्रतियों वाली सभी पुस्तकों की सूची लौटाएं।
सबसे अधिक बिकने वाली पुस्तकें (दहलीज) कार्य करें {
  रिटर्न बुकलिस्ट.फ़िल्टर (
  समारोह (पुस्तक) {पुस्तक वापस करें। बिक्री> = सीमा; }
  );
}
</वाक्यविन्यास हाइलाइट> <code>function</code> की जगह यहाँ e> कीवर्ड का प्रयोग किया गया है <code>lambda</code>, और <code>Array.filter</code> विधि<ref>{{cite web | url = https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/filter | title = array.filter | work = Mozilla Developer Center | date = 10 January 2010 | access-date = 2010-02-09}}</ref> वैश्विक के अतिरिक्त <code>filter</code> कार्य करता है, किन्तु अन्यथा संरचना और कोड का प्रभाव समान होता है।


फ़ंक्शन क्लोजर बना सकता है और इसे वापस कर सकता है, जैसा कि निम्नलिखित उदाहरण में है:
फंक्शन व्युत्पन्न (एफ, डीएक्स) {
  // Return a function that approximates the derivative of f


<वाक्यविन्यास लैंग = जावास्क्रिप्ट>
// using an interval of dx, which should be appropriately small.
// फ़ंक्शन लौटाएं जो f के व्युत्पन्न का अनुमान लगाता है
function derivative(f, dx) {
// डीएक्स के अंतराल का उपयोग करना, जो उचित रूप से छोटा होना चाहिए।
  return function (x) {
फ़ंक्शन डेरिवेटिव (एफ, डीएक्स) {
    return (f(x + dx) - f(x)) / dx;
  वापसी समारोह (एक्स) {
  };
  रिटर्न (एफ(एक्स + डीएक्स) - एफ(एक्स)) / डीएक्स;
}
  };
चूंकि इस स्थितियों में क्लोजर होने से उस फंक्शन के निष्पादन की अवधि समाप्त हो जाती है। जो इसे बनाता है। चर <code>f</code> और <code>dx</code> फंक्शन <code>derivative</code> वापसी के पश्चात् रहते है। यदि निष्पादन ने अपनी सीमा को छोड़ दिया हो और वह अब दिखाई नहीं दे रहे हैं। क्लोजर के बिना भाषाओं में, स्वचालित स्थानीय चर का जीवनकाल समुदाय फ्रेम के निष्पादन के साथ मेल खाता है। जहां उस चर को घोषित किया जाता है। क्लोजर वाली भाषाओं में, चर तब तक उपस्तिथ रहना चाहिए। जब तक कि किसी भी उपस्तिथ क्लोजर में उनका संदर्भ होता है। यह सामान्यतः किसी प्रकार के [[कचरा संग्रह (कंप्यूटर विज्ञान)]] का उपयोग करके कार्यान्वित किया जाता है।
}
</वाक्यविन्यास हाइलाइट>
 
क्योंकि इस स्थितियों में क्लोजर फ़ंक्शन के निष्पादन को समाप्त कर देता है जो इसे बनाता है, चर <code>f</code> और <code>dx</code> समारोह के बाद लाइव <code>derivative</code> रिटर्न, यदि निष्पादन ने अपना दायरा छोड़ दिया हो और वे अब दिखाई नहीं दे रहे हैं। क्लोजर के बिना भाषाओं में, स्वचालित स्थानीय चर का जीवनकाल स्टैक फ्रेम के निष्पादन के साथ मेल खाता है जहां उस चर को घोषित किया जाता है। क्लोजर वाली भाषाओं में, चर तब तक उपस्तिथ रहना चाहिए जब तक कि किसी भी उपस्तिथा क्लोजर में उनके संदर्भ हों। यह सामान्यतः किसी प्रकार के [[कचरा संग्रह (कंप्यूटर विज्ञान)]] का उपयोग करके कार्यान्वित किया जाता है।


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


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


=== अन्य उपयोग ===
=== अन्य उपयोग ===
क्लोजर के कई उपयोग हैं:
क्लोजर के अनेक उपयोग हैं:
* क्योंकि बंद होने से मूल्यांकन में देरी होती है—अर्थात्, वे तब तक कुछ नहीं करते जब तक उन्हें बुलाया नहीं जाता—उनका उपयोग नियंत्रण संरचनाओं को परिभाषित करने के लिए किया जा सकता है। उदाहरण के लिए, स्मॉलटाक की सभी मानक नियंत्रण संरचनाएँ, जिनमें शाखाएँ (यदि/तब/अन्य) और लूप्स (जबकि और के लिए) सम्मिलित हैं, उन वस्तुओं का उपयोग करके परिभाषित की जाती हैं जिनके तरीके क्लोजर स्वीकार करते हैं। उपयोक्ता अपनी स्वयं की नियंत्रण संरचनाओं को भी आसानी से परिभाषित कर सकते हैं।
* चूंकि क्लोजर होने से मूल्यांकन में देरी होती है।अर्थात्, वह तब तक कुछ नहीं करते जब तक उन्हें बुलाया नहीं जाता है।उनका उपयोग नियंत्रण संरचनाओं को परिभाषित करने के लिए किया जा सकता है। उदाहरण के लिए, लघु वार्ता की सभी मानक नियंत्रण संरचनाएँ है। जिनमें शाखाएँ (यदि/तब/अन्य) और छोरों (जबकि और के लिए) सम्मिलित हैं। उन वस्तुओं का उपयोग करके परिभाषित की जाती हैं। जिनकी विधि क्लोजर स्वीकार करते हैं। उपयोक्ता अपनी स्वयं की नियंत्रण संरचनाओं को भी सरलता से परिभाषित कर सकते हैं।
* उन भाषाओं में जो असाइनमेंट को प्रयुक्त करती हैं, ही वातावरण के करीब कई फ़ंक्शन उत्पन्न किए जा सकते हैं, जिससे वे उस वातावरण को बदलकर निजी तौर पर संवाद करने में सक्षम हो जाते हैं। योजना में:
* उन भाषाओं में जो कार्य को प्रयुक्त करती हैं। वातावरण के समीप अनेक फंक्शन उत्पन्न किए जा सकते हैं, जिससे वह उस योजना में वातावरण को परिवर्तित करके व्यक्तिगत रूप से संवाद करने में सक्षम हो जाते हैं।
(define foo #f)
(define bar #f)
(let ((secret-message "none"))
  (set! foo (lambda (msg) (set! secret-message msg)))
  (set! bar (lambda () secret-message)))
(display (bar)) ; prints "none"
(newline)
(foo "meet me by the docks at midnight")
(display (bar)) ; prints "meet me by the docks at midnight"
* नामांकन-उन्मुख प्रोग्रामिंग सिस्टम को प्रयुक्त करने के लिए क्लोजर का उपयोग किया जा सकता है।<ref>{{cite web | url = http://okmij.org/ftp/Scheme/oop-in-fp.txt | title = Re: FP, OO and relations. Does anyone trump the others? | date = 29 December 1999 | access-date = 2008-12-23 | archive-url = https://web.archive.org/web/20081226055307/http://okmij.org/ftp/Scheme/oop-in-fp.txt | archive-date = 26 December 2008 | url-status = dead }}</ref>
नोट: कुछ वक्ता किसी भी डेटा संरचना को कॉल करते हैं। जो विस्तार (प्रोग्रामिंग) शाब्दिक विस्तार वातावरण को क्लोजर से बांधता है। किन्तु यह शब्द सामान्यतः विशेष रूप से फंक्शन को संदर्भित करता है।


<वाक्यविन्यास लैंग = योजना>
== कार्यान्वयन और सिद्धांत ==
(फू #f परिभाषित करें)
क्लोजर सामान्यतः विशेष डेटा संरचना के साथ कार्यान्वित किया जाता है। जिसमें कोड के लिए [[समारोह सूचक|फंक्शन सूचक]] होता है, साथ ही फंक्शन के शाब्दिक पर्यावरण (अर्थात, उपलब्ध चर का समूह) का प्रतिनिधित्व उस समय होता है। जब क्लोजर बनाया गया था। सन्दर्भ देने वाला पर्यावरण गैर-स्थानीय नामों को शाब्दिक वातावरण में संगत चरों के साथ बांधता है। जब क्लोजर बनाया जाता है। इसके अतिरिक्त उनके जीवनकाल को कम से कम क्लोजर के जीवनकाल तक विस्तारित करता है। जब क्लोजर को पश्चात् के समय में अंकित किया जाता है। संभवतः भिन्न शाब्दिक वातावरण के साथ, फंक्शन को इसके गैर-स्थानीय चर के साथ निष्पादित किया जाता है, जो कि क्लोजर द्वारा कब्जा कर लिया गया है, न कि वर्तमान वातावरण के द्वारा कब्जा कर लिया गया है।
(बार #f परिभाषित करें)
 
(चलो ((गुप्त-संदेश कोई नहीं))
  (सेट! फू (लैम्ब्डा (संदेश) (सेट! गुप्त-संदेश संदेश)))
  (सेट! बार (लैम्ब्डा () गुप्त-संदेश)))
 
(प्रदर्शन (बार)); प्रिंट कोई नहीं
(नई पंक्ति)
(आधी रात को मुझे गोदी से मिलो)
(प्रदर्शन (बार)); प्रिंट मुझसे आधी रात को डॉक पर मिलते हैं
</वाक्यविन्यास हाइलाइट>


* ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग सिस्टम को प्रयुक्त करने के लिए क्लोजर का उपयोग किया जा सकता है।<ref>{{cite web | url = http://okmij.org/ftp/Scheme/oop-in-fp.txt | title = Re: FP, OO and relations. Does anyone trump the others? | date = 29 December 1999 | access-date = 2008-12-23 | archive-url = https://web.archive.org/web/20081226055307/http://okmij.org/ftp/Scheme/oop-in-fp.txt | archive-date = 26 December 2008 | url-status = dead }}</ref>
भाषा कार्यान्वयन सरलता से पूर्ण क्लोजर का समर्थन नहीं कर सकता है। यदि इसका कार्यावधि स्मृति मॉडल रैखिक [[स्टैक-आधारित मेमोरी आवंटन|समुदाय-आधारित स्मृति आवंटन]] पर सभी [[स्वचालित चर]] आवंटित करता है। ऐसी भाषाओं में, फंक्शन के वापस आने पर किसी फंक्शन के स्वचालित स्थानीय चरों को हटा दिया जाता है। चूँकि, क्लोजर के लिए यह आवश्यक है कि इसके द्वारा संदर्भित नि: शुल्क चरों संलग्न फंक्शन के निष्पादन से बचे रहते है। अतः उन चरों को आवंटित किया जाना चाहिए। जिससे कि वह तब तक बने रहता है जब तक कि उनकी आवश्यकता नही होती है। सामान्यतः समुदाय के अतिरिक्त संचय आवंटन के माध्यम से और उनके जीवनकाल को प्रबंधित किया जाता है। जिससे कि वह तब तक जीवित रहता है। जब तक कि उन्हें संदर्भित करने वाले सभी क्लोजर उपयोग नही होते है।
नोट: कुछ समया किसी भी डेटा संरचना को कॉल करते हैं जो स्कोप (प्रोग्रामिंग) # लेक्सिकल स्कोपिंग वातावरण को क्लोजर से बांधता है, किन्तु यह शब्द सामान्यतः विशेष रूप से फ़ंक्शंस को संदर्भित करता है।


== कार्यान्वयन और सिद्धांत ==
यह बताता है कि सामान्यतः मूल रूप से क्लोजर का समर्थन करने वाली भाषाएं कचरा संग्रह (कंप्यूटर विज्ञान) का उपयोग क्यों करती हैं। चूँकि विकल्प गैर-स्थानीय चर के मैनुअल स्मृति प्रबंधन हैं। (स्पष्ट रूप से संचय पर आवंटन और किए जाने पर मुक्त) या यदि समुदाय आवंटन का उपयोग करते हैं। तब भाषा के लिए यह स्वीकार करने के लिए कि कुछ उपयोग के स्थितियों [[अपरिभाषित व्यवहार]] की ओर ले जाते है। लटकने वाले सूचक के कारण सी ++ 11 में लैम्ब्डा अभिव्यक्ति के रूप में मुक्त स्वचालित चर<ref>''[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2550.pdf Lambda Expressions and Closures]'' C++ Standards Committee. 29 February 2008.</ref> या जीएनयू सी में स्थिर फंक्शन के रूप में मुक्त स्वचालित चर होता है।<ref>GCC Manual, [https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html 6.4 Nested Functions], "If you try to call the nested function through its address after the containing function exits, all hell breaks loose. If you try to call it after a containing scope level exits, and if it refers to some of the variables that are no longer in scope, you may be lucky, but it's not wise to take the risk. If, however, the nested function does not refer to anything that has gone out of scope, you should be safe."</ref> फनार्ग समस्या (या कार्यात्मक तर्क समस्या) सी या सी ++ जैसी समुदाय-आधारित प्रोग्रामिंग भाषा में प्रथम श्रेणी की वस्तुओं के रूप में फंक्शन को प्रयुक्त करने में कठिनाई का वर्णन करती है। इसी प्रकार [[डी (प्रोग्रामिंग भाषा)]] संस्करण 1 में, यह माना जाता है कि प्रोग्रामर जानता है कि [[प्रतिनिधिमंडल (प्रोग्रामिंग)]] और स्वचालित स्थानीय चर के साथ क्या करना है। चूंकि इसकी परिभाषा के क्षेत्र से लौटने के पश्चात् उनके संदर्भ अमान्य हो जाते है। (स्वचालित स्थानीय चर ढेर पर हैं।) - यह अभी भी अनेक उपयोगी कार्यात्मक पैटर्न की अनुमति देता है। किन्तु जटिल स्थितियों के लिए चर के स्पष्ट संचय आवंटन की आवश्यकता होती है। डी संस्करण 2 ने यह पता लगाने के द्वारा हल किया कि कौन से चर को ढेर पर संग्रहीत किया जाना है और स्वचालित आवंटन करता है। चूंकि डी कचरा संग्रह का उपयोग करता है। अतः दोनों संस्करणों में, चर के उपयोग को ट्रैक करने की कोई आवश्यकता नहीं है, चूंकि वह समीप होते हैं।
क्लोजर सामान्यतः विशेष डेटा संरचना के साथ कार्यान्वित किया जाता है जिसमें [[समारोह सूचक]] होता है, साथ ही फ़ंक्शन के लेक्सिकल पर्यावरण (अर्थात, उपलब्ध चर का सेट) का प्रतिनिधित्व उस समय होता है जब क्लोजर बनाया गया था। सन्दर्भ देने वाला पर्यावरण नाम गैर-स्थानीय नामों को लेक्सिकल वातावरण में संगत चरों के साथ बांधता है, जब क्लोजर बनाया जाता है, इसके अतिरिक्त उनके जीवनकाल को कम से कम क्लोजर के जीवनकाल तक विस्तारित करता है। जब क्लोजर को बाद के समय में अंकित किया जाता है, संभवतः अलग लेक्सिकल वातावरण के साथ, फ़ंक्शन को इसके गैर-स्थानीय चर के साथ निष्पादित किया जाता है, जो कि क्लोजर द्वारा कब्जा कर लिया गया है, न कि वर्तमान वातावरण।


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


यह बताता है कि क्यों, सामान्यतः, मूल रूप से क्लोजर का समर्थन करने वाली भाषाएं कचरा संग्रह (कंप्यूटर विज्ञान) का उपयोग करती हैं। विकल्प गैर-स्थानीय चर के मैनुअल मेमोरी प्रबंधन हैं (स्पष्ट रूप से हीप पर आवंटन और किए जाने पर मुक्त), या, यदि स्टैक आवंटन का उपयोग करते हैं, तो भाषा के लिए यह स्वीकार करने के लिए कि कुछ उपयोग के स्थितियों [[अपरिभाषित व्यवहार]] की ओर ले जाएंगे, लटकने वाले पॉइंटर्स के कारण सी ++ 11 में लैम्ब्डा एक्सप्रेशन के रूप में मुक्त स्वचालित चर<ref>''[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2550.pdf Lambda Expressions and Closures]'' C++ Standards Committee. 29 February 2008.</ref> या GNU C में नेस्टेड फ़ंक्शंस।<ref>GCC Manual, [https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html 6.4 Nested Functions], "If you try to call the nested function through its address after the containing function exits, all hell breaks loose. If you try to call it after a containing scope level exits, and if it refers to some of the variables that are no longer in scope, you may be lucky, but it's not wise to take the risk. If, however, the nested function does not refer to anything that has gone out of scope, you should be safe."</ref> funarg समस्या (या कार्यात्मक तर्क समस्या) सी या सी ++ जैसी स्टैक-आधारित प्रोग्रामिंग भाषा में प्रथम श्रेणी की वस्तुओं के रूप में कार्यों को प्रयुक्त करने में कठिनाई का वर्णन करती है। इसी तरह [[डी (प्रोग्रामिंग भाषा)]] वर्जन 1 में, यह माना जाता है कि प्रोग्रामर जानता है कि [[प्रतिनिधिमंडल (प्रोग्रामिंग)]] और स्वचालित स्थानीय चर के साथ क्या करना है, क्योंकि इसकी परिभाषा के चक्र से लौटने के बाद उनके संदर्भ अमान्य हो जाएंगे (स्वचालित स्थानीय चर ढेर पर हैं) ) - यह अभी भी कई उपयोगी कार्यात्मक पैटर्न की अनुमति देता है, किन्तु जटिल स्थितियों के लिए चर के लिए स्पष्ट हीप आवंटन की आवश्यकता होती है। डी संस्करण 2 ने यह पता लगाने के द्वारा हल किया कि कौन से चर को ढेर पर संग्रहीत किया जाना चाहिए, और स्वचालित आवंटन करता है। क्योंकि डी कचरा संग्रह का उपयोग करता है, दोनों संस्करणों में, चर के उपयोग को ट्रैक करने की कोई आवश्यकता नहीं है क्योंकि वे पास हो गए हैं।
एमएल में, स्थानीय चर शाब्दिक रूप से सीमित होते हैं और अतः समुदाय-जैसे मॉडल को परिभाषित करते है। चूंकि वह मूल्यों के लिए बाध्य हैं और वस्तुओं के लिए नहीं, अतः कार्यान्वयन इन मानों को क्लोजर की डेटा संरचना में कॉपी करने के लिए स्वतंत्र है जो कि अदृश्य प्रोग्रामर है।


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


एमएल में, स्थानीय चर लेक्सिक रूप से स्कॉप्ड होते हैं, और इसलिए स्टैक-जैसे मॉडल को परिभाषित करते हैं, किन्तु चूंकि वे मूल्यों के लिए बाध्य हैं और वस्तुओं के लिए नहीं, कार्यान्वयन इन मानों को क्लोजर की डेटा संरचना में कॉपी करने के लिए स्वतंत्र है जो कि अदृश्य है प्रोग्रामर।
क्लोजर समवर्ती संगणना के [[अभिनेता मॉडल]] में अभिनेताओं से निकटता से संबंधित हैं। जहां फंक्शन के शाब्दिक वातावरण में मूल्यों को परिचित कहा जाता है। [[समवर्ती प्रोग्रामिंग]] भाषाओं में क्लोजर के लिए महत्वपूर्ण मुद्दा यह है कि क्या क्लोजर में चरों को सूचित किया जा सकता है और यदि तब इन अद्यतन को कैसे समक्रमिक किया जा सकता है।अभिनेता इसका समाधान प्रदान करते हैं।<ref>''[https://dspace.mit.edu/handle/1721.1/6935 Foundations of Actor Semantics]'' Will Clinger. MIT Mathematics Doctoral Dissertation. June 1981.</ref>


स्कीम (प्रोग्रामिंग लैंग्वेज), जिसमें डायनेमिक वेरिएबल्स और कचरा संग्रह के साथ [[ALGOL]] जैसी लेक्सिकल स्कोप सिस्टम है, में स्टैक प्रोग्रामिंग मॉडल का अभाव है और यह स्टैक-आधारित भाषाओं की सीमाओं से ग्रस्त नहीं है। योजना में क्लोजर स्वाभाविक रूप से व्यक्त किए जाते हैं। लैम्ब्डा फॉर्म कोड को संलग्न करता है, और इसके पर्यावरण के मुक्त चर कार्यक्रम के भीतर तब तक बने रहते हैं जब तक उन्हें संभवतः एक्सेस किया जा सकता है, और इसलिए उन्हें किसी अन्य योजना अभिव्यक्ति के रूप में स्वतंत्र रूप से उपयोग किया जा सकता है।{{citation needed|date=December 2014}}
क्लोजर फंक्शन वस्तु से निकटता से संबंधित होता हैं। अतः पूर्व से दूसरे में परिवर्तन को [[निष्क्रियता]] या [[लैम्ब्डा उठाना]] के रूप में जाना जाता है। क्लोजर रूपांतरण भी देख सकते है।
क्लोजर समवर्ती संगणना के [[अभिनेता मॉडल]] में अभिनेताओं से निकटता से संबंधित हैं, जहां फ़ंक्शन के शाब्दिक वातावरण में मूल्यों को परिचित कहा जाता है। [[समवर्ती प्रोग्रामिंग]] भाषाओं में क्लोजर के लिए महत्वपूर्ण मुद्दा यह है कि क्या क्लोजर में वेरिएबल्स को अपडेट किया जा सकता है और यदि हां, तो इन अपडेट्स को कैसे सिंक्रोनाइज किया जा सकता है। अभिनेता समाधान प्रदान करते हैं।<ref>''[https://dspace.mit.edu/handle/1721.1/6935 Foundations of Actor Semantics]'' Will Clinger. MIT Mathematics Doctoral Dissertation. June 1981.</ref>
क्लोजर फ़ंक्शन ऑब्जेक्ट्स से निकटता से संबंधित हैं; पूर्व से दूसरे में परिवर्तन को [[निष्क्रियता]] या [[लैम्ब्डा उठाना]] के रूप में जाना जाता है; क्लोजर रूपांतरण भी देखें।{{Citation needed|date=September 2011}}
== शब्दार्थ में अंतर ==
== शब्दार्थ में अंतर ==


=== शाब्दिक वातावरण ===
=== शाब्दिक वातावरण ===
जैसा कि अलग-अलग भाषाओं में हमेशा शाब्दिक वातावरण की सामान्य परिभाषा नहीं होती है, उनके बंद होने की परिभाषा भी भिन्न हो सकती है। लेक्सिकल पर्यावरण की सामान्य रूप से आयोजित न्यूनतम परिभाषा इसे चक्र में बाध्यकारी सभी नामों के सेट के रूप में परिभाषित करती है, और यह भी कि किसी भी भाषा में बंद होने पर कब्जा करना पड़ता है। चूँकि [[चर (प्रोग्रामिंग)]] बाइंडिंग का अर्थ भी भिन्न होता है। अनिवार्य भाषाओं में, चर स्मृति में सापेक्ष स्थानों से जुड़ते हैं जो मूल्यों को संग्रहीत कर सकते हैं। चूँकि बाइंडिंग का सापेक्ष स्थान रनटाइम पर नहीं बदलता है, किन्तु बाउंड लोकेशन में मान बदल सकता है। ऐसी भाषाओं में, चूंकि क्लोजर बाइंडिंग को कैप्चर करता है, वेरिएबल पर कोई भी ऑपरेशन, चाहे क्लोजर से किया गया हो या नहीं, उसी रिलेटिव मेमोरी लोकेशन पर किया जाता है। इसे अधिकांशतः चर को संदर्भ द्वारा कैप्चर करना कहा जाता है। यहां ईसीएमएस्क्रिप्ट में अवधारणा को चित्रित करने वाला उदाहरण दिया गया है, जो ऐसी ही भाषा है:
जैसा कि भिन्न-भिन्न भाषाओं में हमेशा शाब्दिक वातावरण की सामान्य परिभाषा नहीं होती है, उनके क्लोजर होने की परिभाषा भी भिन्न हो सकती है। शाब्दिक पर्यावरण की सामान्य रूप से आयोजित न्यूनतम परिभाषा इसे क्षेत्र में बाध्यकारी सभी नामों के समूह के रूप में परिभाषित करती है और यह किसी भी भाषा में क्लोजर होने पर कब्जा करना पड़ता है। चूँकि [[चर (प्रोग्रामिंग)]] आबद्धिंग का अर्थ भी भिन्न होता है। अनिवार्य भाषाओं में, चर स्मृति में सापेक्ष स्थानों से जुड़ते हैं जो मूल्यों को संग्रहीत कर सकते हैं। चूँकि आबद्धिंग का सापेक्ष स्थान कार्यावधि पर परिवर्तितता नहीं होता है, किन्तु सीमित स्थिति में मान परिवर्तित हो सकता है। ऐसी भाषाओं में, चूंकि क्लोजर आबद्धिंग को अधिकृत करता है। चर पर कोई भी ऑपरेशन, चाहे क्लोजर से किया गया हो या नहीं, उसी रिलेटिव स्मृति स्थिति पर किया जाता है। इसे अधिकांशतः चर को संदर्भ द्वारा अधिकृत करना कहा जाता है। यहां ईसीएमए लिपि में अवधारणा को चित्रित करने वाला उदाहरण दिया गया है। जो ऐसी ही भाषा है।
 
// Javascript
<वाक्यविन्यास लैंग = [[एकमा स्क्रिप्ट]]>
var f, g;
// जावास्क्रिप्ट
function foo() {
वार एफ, जी;
  var x;
समारोह फू () {
  f = function() { return ++x; };
  वार एक्स;
  g = function() { return --x; };
  च = समारोह () {वापसी ++x; };
  x = 1;
  जी = समारोह () {वापसी --x; };
  alert('inside foo, call to f(): ' + f());
  एक्स = 1;
}
  चेतावनी ('फू के अंदर, एफ को कॉल करें):' + एफ ());
foo(); // 2
}
alert('call to g(): ' + g()); // 1 (--x)
फू (); // 2
alert('call to g(): ' + g()); // 0 (--x)
चेतावनी ('जी को कॉल करें):' + जी ()); // 1 (--x)
alert('call to f(): ' + f()); // 1 (++x)
चेतावनी ('जी को कॉल करें):' + जी ()); // 0 (--x)
alert('call to f(): ' + f()); // 2 (++x)
चेतावनी ('कॉल टू एफ ():' + एफ ()); // 1 (++x)
फंक्शन <code>foo</code> और चरों <code>f</code> और <code>g</code> द्वारा संदर्भित क्लोजर सभी स्थानीय चर <code>x</code> द्वारा दर्शाए गए समान सापेक्ष स्मृति स्थान का उपयोग करते हैं।
चेतावनी ('कॉल टू एफ ():' + एफ ()); // 2 (++x)
</वाक्यविन्यास हाइलाइट>


समारोह <code>foo</code> और वेरिएबल्स द्वारा संदर्भित क्लोजर <code>f</code> और <code>g</code> सभी स्थानीय चर द्वारा दर्शाए गए समान सापेक्ष स्मृति स्थान का उपयोग करते हैं <code>x</code>.
कुछ उदाहरणों में उपरोक्त व्यवहार अवांछनीय हो सकता है और भिन्न शाब्दिक समापन को बांधना आवश्यक है। पुनः ईसीएमए लिपि में <code>Function.bind()</code>का उपयोग करके किया जाता है।


कुछ उदाहरणों में उपरोक्त व्यवहार अवांछनीय हो सकता है, और अलग शाब्दिक समापन को बांधना आवश्यक है। फिर से ईसीएमएस्क्रिप्ट में, इसका उपयोग करके किया जाएगा <code>Function.bind()</code>.
=== '''उदाहरण 1: असीमित चर का संदर्भ''' ===
<ref>{{cite web |title=Function.prototype.bind() |url=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind |website=MDN Web Docs |access-date=20 November 2018}}</ref>
  var module = {


=== उदाहरण 1: अनबाउंड वेरिएबल === का संदर्भ
  x: 42,
<ref>{{cite web |title=Function.prototype.bind() |url=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind |website=MDN Web Docs |access-date=20 November 2018}}</ref>
  getX: function() {return this.x; }
<वाक्यविन्यास लैंग = एक्मास्क्रिप्ट>
}
वार मॉड्यूल = {
var unboundGetX = module.getX;
  एक्स: 42,
console.log(unboundGetX()); // The function gets invoked at the global scope
  getX: फ़ंक्शन () {इसे वापस करें। x; }
// emits undefined as 'x' is not specified in global scope.
}
var अनबाउंडगेटएक्स = मॉड्यूल.गेटएक्स;
var boundGetX = unboundGetX.bind(module); // specify object module as the closure
कंसोल.लॉग (अनबाउंडगेटएक्स ()); // फ़ंक्शन को वैश्विक चक्र में प्रयुक्त किया जाता है
// अपरिभाषित उत्सर्जित करता है क्योंकि 'x' वैश्विक चक्र में निर्दिष्ट नहीं है।


var बाउंडगेटएक्स = अनबाउंडगेटएक्स.बाइंड (मॉड्यूल); // ऑब्जेक्ट मॉड्यूल को क्लोजर के रूप में निर्दिष्ट करें
console.log(boundGetX()); // emits 42
कंसोल.लॉग (बाउंडगेटएक्स ()); // 42 का उत्सर्जन करता है
</वाक्यविन्यास हाइलाइट>


=== उदाहरण 2: बाध्य चर के लिए आकस्मिक संदर्भ ===
=== उदाहरण 2: बाध्य चर के लिए आकस्मिक संदर्भ ===


इस उदाहरण के लिए अपेक्षित व्यवहार यह होगा कि क्लिक किए जाने पर प्रत्येक लिंक को अपनी आईडी छोड़नी चाहिए; किन्तु क्योंकि वेरिएबल 'ई' उपरोक्त चक्र से जुड़ा हुआ है, और क्लिक पर आलसी मूल्यांकन किया गया है, वास्तव में क्या होता है कि प्रत्येक क्लिक ईवेंट अंतिम तत्व की आईडी को लूप के अंत में बंधे 'तत्व' में उत्सर्जित करता है।<ref>{{cite web |title=Closures |url=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#Creating_closures_in_loops_A_common_mistake |website=MDN Web Docs |access-date=20 November 2018}}</ref>
इस उदाहरण के लिए अपेक्षित व्यवहार यह होता है कि क्लिक किए जाने पर प्रत्येक लिंक को अपनी आईडी छोड़नी होती है। किन्तु चर 'ई' उपरोक्त क्षेत्र से जुड़ा हुआ है और क्लिक पर मुक्त मूल्यांकन किया गया है। वास्तव में यह होता है कि प्रत्येक क्लिक आयोजन के अंतिम तत्व की आईडी को लूप के अंत में बंधे 'तत्व' में उत्सर्जित करता है।<ref>{{cite web |title=Closures |url=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#Creating_closures_in_loops_A_common_mistake |website=MDN Web Docs |access-date=20 November 2018}}</ref>
<nowiki><वाक्यविन्यास लैंग = एक्मास्क्रिप्ट>
var एलिमेंट्स = document.getElementsByTagName ('ए');
// गलत: ई 'फॉर' लूप वाले फ़ंक्शन के लिए बाध्य है, न कि हैंडल को बंद करने के लिए
के लिए (तत्वों का संस्करण) {e.onclick = फ़ंक्शन हैंडल () {अलर्ट (e.id);}}
</वाक्यविन्यास हाइलाइट>
यहाँ फिर से परिवर्तनशील </nowiki><code>e</code> का उपयोग करके ब्लॉक के चक्र से बंधे होने की आवश्यकता होगी <code>handle.bind(this)</code> या <code>let</code> कीवर्ड।


दूसरी ओर, कई कार्यात्मक भाषाएं, जैसे एमएल (प्रोग्रामिंग भाषा), चर को सीधे मानों से बांधती हैं। इस स्थितियों में, चूंकि बार बाध्य होने के बाद चर के मान को बदलने का कोई विधि नहीं है, राज्य को बंद करने के बीच साझा करने की कोई आवश्यकता नहीं है - वे केवल उसी मान का उपयोग करते हैं। इसे अधिकांशतः चर को मान द्वारा कैप्चर करना कहा जाता है। जावा के स्थानीय और अनाम वर्ग भी इस श्रेणी में आते हैं - उन्हें होने के लिए कैप्चर किए गए स्थानीय चर की आवश्यकता होती है <code>final</code>, जिसका अर्थ यह भी है कि राज्य को साझा करने की कोई आवश्यकता नहीं है।
<code>var elements= document.getElementsByTagName('a');</code>


कुछ भाषाएँ आपको चर या उसके स्थान के मान को कैप्चर करने के बीच चयन करने में सक्षम बनाती हैं। उदाहरण के लिए, सी ++ 11 में, कैप्चर किए गए चर या तो घोषित किए जाते हैं <code>[&]</code>, जिसका अर्थ है संदर्भ द्वारा या साथ में कब्जा कर लिया गया <code>[=]</code>, जिसका अर्थ है मूल्य द्वारा कब्जा कर लिया गया।
<code>//Incorrect: e is bound to the function containing the 'for' loop, not the closure of "handle"</code>


फिर भी और सबसेट, [[आलसी मूल्यांकन]] कार्यात्मक भाषाएं जैसे [[हास्केल (प्रोग्रामिंग भाषा)]], मूल्यों के अतिरिक्त भविष्य की संगणनाओं के परिणामों के लिए चर को बांधती हैं। हास्केल में इस उदाहरण पर विचार करें:
<code>for (var e of elements){ e.onclick=function handle(){ alert(e.id);} }</code> 


<वाक्यविन्यास लैंग = हैकेल>
यहाँ पुनः परिवर्तनशील <code>e</code> का उपयोग करके ब्लॉक के क्षेत्र से बंधे होने पर <code>handle.bind(this)</code> या <code>let</code>संपर्क की आवश्यकता होती है।
-- हास्केल
foo :: भिन्नात्मक a => a -> a -> (a -> a)
फू x y = (\z -> z + r)
  जहां आर = एक्स / वाई


f :: भिन्नात्मक a => a -> a
दूसरी ओर, अनेक कार्यात्मक भाषाएं, जैसे एमएल (प्रोग्रामिंग भाषा), चर को सीधे मानों से बांधती हैं। इस स्थितियों में, चूंकि बाध्य होने के पश्चात् चर के मान को परिवर्तित करने की कोई विधि नहीं है। अतः राज्य को क्लोजर करने के मध्य साझा करने की कोई आवश्यकता नहीं है। - वह केवल उसी मान का उपयोग करते हैं। इसे अधिकांशतः चर को मान द्वारा अधिकृत करना कहा जाता है। सामान्यतः जावा के स्थानीय और अनाम वर्ग भी इस श्रेणी में आते हैं। उन्हें <code>final</code>होने के लिए अधिकृत किए गए स्थानीय चर की आवश्यकता होती है। जिसका अर्थ यह भी है कि राज्य को साझा करने की कोई आवश्यकता नहीं है।
एफ = फू 1 0


मुख्य = प्रिंट (एफ 123)
कुछ भाषाएँ आपको चर या उसके स्थान के मान को अधिकृत करने के मध्य चयन करने में सक्षम बनाती हैं। उदाहरण के लिए, सी ++ 11 में, अधिकृत किए गए चर <code>[&]</code> या <code>[=]</code> तब घोषित किए जाते हैं। जिसका अर्थ है संदर्भ द्वारा या साथ में कब्जा कर लिया गया है।
</वाक्यविन्यास हाइलाइट>


का बंधन <code>r</code> फ़ंक्शन के भीतर परिभाषित क्लोजर द्वारा कैप्चर किया गया <code>foo</code> गणना के लिए है <code>(x / y)</code>—जो इस स्थितियों में शून्य से विभाजन में परिणत होता है। चूँकि, चूंकि यह अभिकलन है जो कैप्चर किया गया है, न कि मान, त्रुटि केवल तभी प्रकट होती है जब क्लोजर का आह्वान किया जाता है, और वास्तव में कैप्चर किए गए बाइंडिंग का उपयोग करने का प्रयास करता है।
फिर भी और उपसमूह, [[आलसी मूल्यांकन|मुक्त मूल्यांकन]] कार्यात्मक भाषाएं जैसे [[हास्केल (प्रोग्रामिंग भाषा)]], मूल्यों के अतिरिक्त भविष्य की संगणनाओं के परिणामों के लिए चर को बांधती हैं। हास्केल में इस उदाहरण पर विचार कर सकते है।
-- Haskell
foo :: Fractional a => a -> a -> (a -> a)
foo x y = (\z -> z + r)
          where r = x / y
f :: Fractional a => a -> a
f = foo 1 0


=== जा रहा बंद ===
फिर भी अधिक अंतर स्वयं को अन्य व्याख्यात्मक रूप से निर्मित निर्माणों के व्यवहार में प्रकट करते हैं, जैसे कि <code>return</code>, <code>break</code> और <code>continue</code> कथन। इस तरह के निर्माण, सामान्य रूप से, संलग्न नियंत्रण विवरण (के स्थितियों में) द्वारा स्थापित पलायन निरंतरता को प्रयुक्त करने के संदर्भ में माना जा सकता है <code>break</code> और <code>continue</code>, इस तरह की व्याख्या के लिए पुनरावर्ती फ़ंक्शन कॉल के संदर्भ में लूपिंग निर्माणों पर विचार करने की आवश्यकता होती है)। कुछ भाषाओं में, जैसे ईसीएमएस्क्रिप्ट, <code>return</code> कथन के संबंध में व्याख्यात्मक रूप से आंतरिक रूप से क्लोजर द्वारा स्थापित निरंतरता को संदर्भित करता है- इस प्रकार, ए <code>return</code> क्लोजर के भीतर उस कोड को नियंत्रण स्थानांतरित करता है जिसने इसे बुलाया था। चूँकि, स्मॉलटॉक में, सतही रूप से समान ऑपरेटर <code>^</code> किसी भी हस्तक्षेप करने वाले नेस्टेड क्लोजर के एस्केप निरंतरता को अनदेखा करते हुए, विधि आमंत्रण के लिए स्थापित एस्केप निरंतरता को आमंत्रित करता है। क्लोजर के कोड के अंत तक पहुंचकर किसी विशेष क्लोजर की एस्केप निरंतरता को केवल स्मॉलटाक में प्रयुक्त किया जा सकता है। ईसीएमएस्क्रिप्ट और स्मॉलटाक में निम्नलिखित उदाहरण अंतर को उजागर करते हैं:


<वाक्यविन्यास लैंग = स्मॉलटॉक>
  main = print (f 123)
  गपशप
फंक्शन के अंदर परिभाषित क्लोजर द्वारा अधिकृत किया गया <code>r</code> का बंधन गणना <code>(x / y)</code> के लिए है। जो इस स्थितियों में शून्य से विभाजन में परिणत होता है। चूंकि यह अभिकलन है जो अधिकृत किया गया है। न कि मान, त्रुटि केवल तभी प्रकट होती है। जब क्लोजर का आह्वान किया जाता है,और वास्तव में अधिकृत किए गए आबद्धिंग का उपयोग करने का प्रयास करता है।
फू
  | एक्सएस |
  xs := #(1 2 3 4).
  xs करते हैं: [:x | ^ एक्स]।
  ^ 0
छड़
  ट्रांसक्रिप्ट शो: (सेल्फ फू प्रिंटस्ट्रिंग) प्रिंट 1
</वाक्यविन्यास हाइलाइट>


<वाक्यविन्यास लैंग = जावास्क्रिप्ट>
=== क्लोजर छोड़ना ===
// ईसीएमएस्क्रिप्ट
सामान्यतः अधिक अंतर स्वयं को अन्य व्याख्यात्मक रूप से निर्मित निर्माणों के व्यवहार में प्रकट करते हैं। जैसे कि <code>return</code>, <code>break</code> और <code>continue</code> कथन इस प्रकार के निर्माण, सामान्य रूप से, संलग्न नियंत्रण विवरण (के स्थितियों में) द्वारा स्थापित पलायन निरंतरता को प्रयुक्त करने के संदर्भ में माना जा सकता है। <code>break</code> और <code>continue</code> इस प्रकार की व्याख्या के लिए पुनरावर्ती फंक्शन कॉल के संदर्भ में लूपिंग निर्माणों पर विचार करने की आवश्यकता होती है)। कुछ भाषाओं में, जैसे ईसीएमए लिपि, <code>return</code>कथन के संबंध में व्याख्यात्मक रूप से आंतरिक रूप से क्लोजर द्वारा स्थापित निरंतरता को संदर्भित करता है। इस प्रकार, ए  <code>return</code>क्लोजर के अंदर उस कोड को नियंत्रण स्थानांतरित करता है जिसने इसे बुलाया था। चूँकि, लघु वार्ता में, सतही रूप से समान ऑपरेटर <code>^</code> किसी भी हस्तक्षेप करने वाले स्थिर क्लोजर के एस्केप निरंतरता को अनदेखा करते हुए, विधि आमंत्रण के लिए स्थापित एस्केप निरंतरता को आमंत्रित करता है। क्लोजर के कोड के अंत तक पहुंचकर किसी विशेष क्लोजर की एस्केप निरंतरता को केवल लघु वार्ता में प्रयुक्त किया जा सकता है। ईसीएमए लिपि और लघु वार्ता में निम्नलिखित उदाहरण अंतर को उजागर करते हैं।
समारोह फू () {
"Smalltalk"
  वार xs = [1, 2, 3, 4];
foo
  xs.forEach (फ़ंक्शन (x) {वापसी x;});
  | xs |
  वापसी 0;
  xs := #(1 2 3 4).
}
  xs do: [:x | ^x].
चेतावनी (फू ()); // प्रिंट 0
  ^0
</वाक्यविन्यास हाइलाइट>
bar
  Transcript show: (self foo printString) "prints 1"


उपरोक्त कोड स्निपेट्स अलग तरह से व्यवहार करेंगे क्योंकि स्मॉलटाक <code>^</code> ऑपरेटर और जावास्क्रिप्ट <code>return</code> ऑपरेटर अनुरूप नहीं हैं। ईसीएमएस्क्रिप्ट उदाहरण में, <code>return x</code> का नया पुनरावृति प्रारंभ करने के लिए आंतरिक समापन को छोड़ देगा <code>forEach</code> पाश, जबकि स्मालटाक उदाहरण में, <code>^x</code> लूप को निरस्त कर देगा और विधि से वापस आ जाएगा <code>foo</code>.
// ECMAScript
function foo() {
  var xs = [1, 2, 3, 4];
  xs.forEach(function (x) { return x; });
  return 0;
}
alert(foo()); // prints 0
उपरोक्त कोड के टुकड़े भिन्न प्रकार से व्यवहार करते है। चूंकि लघु वार्ता <code>^</code> ऑपरेटर और जावालिपि <code>return</code> ऑपरेटर अनुरूप नहीं हैं। ईसीएमए लिपि उदाहरण में, <code>return x</code> का नया पुनरावृति प्रारंभ करने के लिए आंतरिक समापन को छोड़ देता है जिससे कि लघु वार्ता उदाहरण में, <code>^x</code> लूप को निरस्त कर देता है और विधि <code>foo</code> से वापस आ जाता है।


[[सामान्य लिस्प]] निर्माण प्रदान करता है जो उपरोक्त कार्यों में से किसी को व्यक्त कर सकता है: लिस्प <code>(return-from foo x)</code> स्मॉलटाक के रूप में व्यवहार करता है <code>^x</code>, जबकि लिस्प <code>(return-from nil x)</code> जावास्क्रिप्ट के रूप में व्यवहार करता है <code>return x</code>. इसलिए, स्मॉलटॉक कैप्चर किए गए एस्केप निरंतरता को उस सीमा तक जीवित रहने के लिए संभव बनाता है जिसमें इसे सफलतापूर्वक प्रयुक्त किया जा सकता है। विचार करना:
अधिकांशतः [[सामान्य लिस्प]] निर्माण प्रदान करता है। जो उपरोक्त फंक्शन में से किसी को व्यक्त कर सकता है। लिस्प <code>(return-from foo x)</code> लघु वार्ता <code>^x</code> के रूप में व्यवहार करता है। जिससे कि लिस्प <code>(return-from nil x)</code> जावालिपि <code>return x</code> के रूप में व्यवहार करता है। अतः, लघु वार्ता अधिकृत किए गए एस्केप निरंतरता को उस सीमा तक जीवित रहने के लिए संभव बनाता है। जिसमें इसे सफलतापूर्वक प्रयुक्त किया जा सकता है। विचार करना,
"Smalltalk"
foo
    ^[ :x | ^x ]
bar
    | f |
    f := self foo.
    f value: 123 "error!"


<वाक्यविन्यास लैंग = स्मॉलटॉक>
जब क्लोजर विधि द्वारा <code>foo</code> द्वारा वापस किए गये क्लोजर को प्रयुक्त किया जाता है, यह क्लोजर बनाने वाले <code>foo</code> के आह्वान से मान वापस करने का प्रयास करता है। चूँकि वह कॉल पहले ही वापस आ चुकी है और लघु वार्ता विधि मंगलाचरण मॉडल अनेक वापसी की सुविधा के लिए [[स्पेगेटी ढेर]] अनुशासन का पालन नहीं करता है। इस ऑपरेशन के परिणामस्वरूप त्रुटि होती है।
गपशप
फू
  ^[ :x | ^x]
छड़
  | एफ |
  च�:= स्वयं फू.
  एफ मान: 123 त्रुटि!
</वाक्यविन्यास हाइलाइट>


जब बंद विधि द्वारा वापस आ गया <code>foo</code> आह्वान किया जाता है, यह के आह्वान से मान वापस करने का प्रयास करता है <code>foo</code> जिसने बंद बनाया। चूँकि वह कॉल पहले ही वापस आ चुकी है और स्मॉलटाक विधि मंगलाचरण मॉडल कई रिटर्न की सुविधा के लिए [[स्पेगेटी ढेर]] अनुशासन का पालन नहीं करता है, इस ऑपरेशन के परिणामस्वरूप त्रुटि होती है।
कुछ भाषाएँ, जैसे [[रूबी (प्रोग्रामिंग भाषा)]], प्रोग्रामर को <code>return</code> कब्जा करने की विधि चुनने में सक्षम बनाती हैं। रूबी में उदाहरण,
# Ruby
# Closure using a Proc
def foo
  f = Proc.new { return "return from foo from inside proc" }
  f.call # control leaves foo here
  return "return from foo"
end
# Closure using a lambda
def bar
  f = lambda { return "return from lambda" }
  f.call # control does not leave bar here
  return "return from bar"
end
puts foo # prints "return from foo from inside proc"
puts bar # prints "return from bar"<br />
दोनों <code>Proc.new</code> और <code>lambda</code> इस उदाहरण में क्लोजर बनाने के विधि हैं। किन्तु इस प्रकार से बनाए गए क्लोजर <code>return</code> कथन के शब्दार्थ इसके संबंध में भिन्न हैं।


कुछ भाषाएँ, जैसे [[रूबी (प्रोग्रामिंग भाषा)]], प्रोग्रामर को रास्ता चुनने में सक्षम बनाती हैं <code>return</code> कब्जा कर लिया है। रूबी में उदाहरण:
योजना (प्रोग्रामिंग भाषा) में, <code>return</code> नियंत्रण की परिभाषा और कार्यक्षेत्र स्पष्ट है। ( उदाहरण के लिए केवल अनैतिक रूप से 'वापसी' नाम दिया गया है।) निम्नलिखित रूबी प्रतिरूप का सीधा अनुवाद है।
 
<वाक्यविन्यास लैंग = रूबी>
# माणिक
 
# प्रोक का उपयोग कर बंद करें
डेफ फू
  f = Proc.new { foo से अंदर की खरीद से वापसी वापसी}
  f.call # control फू को यहां छोड़ देता है
  फू से वापसी
अंत
 
# लैम्ब्डा का उपयोग करके बंद करें
डेफ बार
  f = लैम्ब्डा {लैम्ब्डा से रिटर्न रिटर्न}
  f.call # नियंत्रण यहां बार नहीं छोड़ता है
  बार से वापसी वापसी
अंत
 
पुट फू # प्रिंट फू फ्रॉम इनसाइड प्रो
बार डालता है # बार से रिटर्न प्रिंट करता है
</वाक्यविन्यास हाइलाइट>
 
दोनों <code>Proc.new</code> और <code>lambda</code> इस उदाहरण में क्लोजर बनाने के तरीके हैं, किन्तु इस तरह से बनाए गए क्लोजर के शब्दार्थ इसके संबंध में भिन्न हैं <code>return</code> कथन।
 
स्कीम (प्रोग्रामिंग लैंग्वेज) में, की परिभाषा और कार्यक्षेत्र <code>return</code> नियंत्रण कथन स्पष्ट है (और उदाहरण के लिए केवल मनमाने ढंग से 'वापसी' नाम दिया गया है)निम्नलिखित रूबी नमूने का सीधा अनुवाद है।
 
<वाक्यविन्यास लैंग = योजना>
; योजना
; योजना
(कॉल/सीसी कॉल-साथ-वर्तमान-निरंतरता को परिभाषित करें)
(कॉल/सीसी कॉल-साथ-वर्तमान-निरंतरता को परिभाषित कर सकते है।)


(परिभाषित करें (फू)
(परिभाषित करें (फू)
   (कॉल/सीसी
   ; Scheme
  (लैम्ब्डा (वापसी)
  (परिभाषित करें (एफ) (अंदर से फू से वापसी वापसी))
  (एफ)�; नियंत्रण यहां फू छोड़ देता है
  (फू से वापसी वापसी))))
 
(परिभाषित करें (बार)
  (कॉल/सीसी
  (लैम्ब्डा (वापसी)
  (परिभाषित करें (एफ) (कॉल/सीसी (लैम्ब्डा (वापसी) (लैम्ब्डा से वापसी))))
  (एफ)�; नियंत्रण यहां बार नहीं छोड़ता
  (बार से वापसी वापसी))))


(प्रदर्शन (फू)); प्रिंट अंदर से फू से वापस आते हैं
(define call/cc call-with-current-continuation)
(नई पंक्ति)
(प्रदर्शन (बार)); प्रिंट बार से वापस आते हैं
(define (foo)
</वाक्यविन्यास हाइलाइट>
  (call/cc
    (lambda (return)
      (define (f) (return "return from foo from inside proc"))
      (f) ; control leaves foo here
      (return "return from foo"))))
(define (bar)
  (call/cc
    (lambda (return)
      (define (f) (call/cc (lambda (return) (return "return from lambda"))))
      (f) ; control does not leave bar here
      (return "return from bar"))))
(display (foo)) ; prints "return from foo from inside proc"
(newline)
(display (bar)) ; prints "return from bar"


== क्लोजर-जैसी संरचनाएं ==
== क्लोजर-जैसी संरचनाएं ==
कुछ भाषाओं में विशेषताएं होती हैं जो क्लोजर के व्यवहार का अनुकरण करती हैं। Java, C++, Objective-C, C#, VB.NET, और D जैसी भाषाओं में, ये विशेषताएँ भाषा के वस्तु-उन्मुख प्रतिमान का परिणाम हैं।
सामान्यतः कुछ भाषाओं में विशेषताएं होती हैं। जो क्लोजर के व्यवहार का अनुकरण करती हैं। जावा, सी++, उद्देश्य सी, सी#, वीबी.नेट और डी जैसी भाषाओं में, ये विशेषताएँ भाषा के वस्तु-उन्मुख प्रतिमान का परिणाम हैं।


=== कॉलबैक (सी) ===
=== कॉलबैक (सी) ===
कुछ [[सी (प्रोग्रामिंग भाषा)]] पुस्तकालय समर्थन करते हैं
सामान्यतः कुछ पुस्तकालय [[कॉलबैक]] [[सी (प्रोग्रामिंग भाषा)]] समर्थन करते हैं। पुस्तकालय के साथ [[कॉलबैक (कंप्यूटर विज्ञान)]] पंजीकृत करते समय इसे कभी-कभी दो मान प्रदान करके कार्यान्वित किया जाता है। उपयोगकर्ता की पसंद के अनैतिक डेटा के लिए फ़ंक्शन सूचक और और <code>void*</code>सूचक होता है। जब पुस्तकालय कॉलबैक फंक्शन निष्पादित करता है तब यह डेटा सूचक के साथ गुजरता है। यह कॉलबैक को राज्य को बनाये रखने और पुस्तकालय के साथ पंजीकृत होने के समय कैप्चर की गई जानकारी को संदर्भित करने में सक्षम बनाता है। मुहावरा कार्यक्षमता में क्लोजर होने के समान है। किन्तु वाक्य - विन्यास में नहीं <code>void*</code> सूचक टाइप सुरक्षित नहीं है, चूँकि यह सी मुहावरा सी #, हास्केल या एमएल में टाइप-सुरक्षित क्लोजर से भिन्न है।
[[कॉलबैक (कंप्यूटर विज्ञान)]] एस। यह है
कभी-कभी दो मान प्रदान करके कार्यान्वित किया जाता है जब
लाइब्रेरी के साथ कॉलबैक पंजीकृत करना: फ़ंक्शन
सूचक और अलग <code>void*</code> के लिए सूचक
उपयोगकर्ता की पसंद का मनमाना डेटा। जब पुस्तकालय
कॉलबैक फ़ंक्शन निष्पादित करता है, यह डेटा के साथ गुजरता है
सूचक। यह कॉलबैक को राज्य और बनाए रखने में सक्षम बनाता है
उस समय कैप्चर की गई जानकारी को संदर्भित करने के लिए
पुस्तकालय के साथ पंजीकृत। मुहावरा समान है
कार्यक्षमता में बंद, किन्तु सिंटैक्स में नहीं।
<code>void*</code> de> पॉइंटर [[प्रकार की सुरक्षा]] नहीं है इसलिए यह C
सी #, हास्केल या एमएल में टाइप-सेफ क्लोजर से मुहावरा अलग है।
 
जीयूआई [[विजेट टूलकिट]] में कॉलबैक का व्यापक रूप से उपयोग किया जाता है
सामान्य को जोड़कर [[घटना-संचालित प्रोग्रामिंग]] प्रयुक्त करें
ग्राफिकल विगेट्स के कार्य (मेनू, बटन, चेक बॉक्स,
स्लाइडर्स, स्पिनर्स, आदि) एप्लिकेशन-विशिष्ट कार्यों के साथ
आवेदन के लिए विशिष्ट वांछित व्यवहार को प्रयुक्त करना।
 
==== नेस्टेड फ़ंक्शन और फ़ंक्शन पॉइंटर (सी) ====
जीसीसी विस्तार के साथ, [https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html नेस्टेड फ़ंक्शन] का उपयोग किया जा सकता है और फ़ंक्शन पॉइंटर क्लोजर का अनुकरण कर सकता है, बशर्ते फ़ंक्शन युक्त चक्र से बाहर न हो।
निम्न उदाहरण अमान्य है क्योंकि <code>adder</code> शीर्ष-स्तरीय परिभाषा है (संकलक संस्करण के आधार पर, यह अनुकूलन के बिना संकलित होने पर सही परिणाम उत्पन्न कर सकता है, अर्थात <code>-O0</code>):
 
<वाक्यविन्यास प्रकाश लैंग = सी>
#सम्मिलित <stdio.h>


टाइपपीफ इंट (*fn_int_to_int)(int); // फ़ंक्शन का प्रकार int->int
आवेदन के लिए विशिष्ट वांछित व्यवहार को प्रयुक्त करने वाले आवेदन-विशिष्ट कार्यों के साथ ग्राफिकल विगेट्स (मेनू, बटन, चेक बॉक्स, स्लाइडर्स, स्पिनर्स, आदि) के सामान्य को जोड़कर [[घटना-संचालित प्रोग्रामिंग]] प्रयुक्त करने के लिए जीयूआई [[विजेट टूलकिट]] में कॉलबैक का व्यापक रूप से उपयोग किया जाता है।


fn_int_to_int योजक (पूर्णांक संख्या) {
==== स्थिर फंक्शन और फंक्शन सूचक (सी) ====
  इंट ऐड (इंट वैल्यू) { रिटर्न वैल्यू + नंबर; }
जीसीसी विस्तार के साथ, [https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html स्थिर फंक्शन] का उपयोग किया जा सकता है और फंक्शन सूचक क्लोजर का अनुकरण कर सकता है। अतः फंक्शन युक्त क्षेत्र से बाहर नही होता है। निम्न उदाहरण अमान्य है। चूंकि  <code>adder</code> शीर्ष-स्तरीय परिभाषा है। (संकलक संस्करण के आधार पर, यह अनुकूलन के बिना संकलित होने पर सही परिणाम उत्पन्न कर सकता है। अर्थात <code>-O0</code>):
  वापसी और जोड़ें; // और ऑपरेटर यहाँ वैकल्पिक है क्योंकि C में फ़ंक्शन का नाम पॉइंटर है जो स्वयं की ओर इशारा करता है
#include <stdio.h>
}
typedef int (*fn_int_to_int)(int); // type of function int->int
fn_int_to_int adder(int number) {
  int add (int value) { return value + number; }
  return &add; // & operator is optional here because the name of a function in C is a pointer pointing on itself
}
int main(void) {
  fn_int_to_int add10 = adder(10);
  printf("%d\n", add10(1));
  return 0;
किन्तु <code>adder</code> (और, वैकल्पिक रूप से, <code>typedef</code>) में <code>main</code> इसे वैध बनाता है।
  #include <stdio.h>


पूर्णांक मुख्य (शून्य) {
int main(void) {
  fn_int_to_int add10 = योजक (10);
  typedef int (*fn_int_to_int)(int); // type of function int->int
  प्रिंटफ (% डी \ n, 10 (1) जोड़ें);
 
  वापसी 0;
  fn_int_to_int adder(int number) {
}
    int add (int value) { return value + number; }
</वाक्यविन्यास हाइलाइट>
    return add;
  }
 
  fn_int_to_int add10 = adder(10);
  printf("%d\n", add10(1));
  return 0;
यदि इसे क्रियान्वित किया जाता है तब यह आशा के अनुसार <code>11</code> मुद्रण करता है।


किन्तु चल रहा है <code>adder</code> (और, वैकल्पिक रूप से, <code>typedef</code>) में <code>main</code> इसे वैध बनाता है:
=== स्थानीय वर्ग और लैम्ब्डा फंक्शन (जावा) ===
[[जावा (प्रोग्रामिंग भाषा)]] कक्षाओं को [[क्लास (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)|(वस्तु-उन्मुख प्रोग्रामिंग)]] को [[विधि (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)|विधि (वस्तु-उन्मुख प्रोग्रामिंग)]] के अंदर परिभाषित करने में सक्षम बनाता है। इन्हें स्थानीय वर्ग कहा जाता है। जब ऐसी कक्षाओं का नाम नहीं दिया जाता है। तब उन्हें [[अनाम वर्ग]] (या अनाम आंतरिक वर्ग) के रूप में जाना जाता है। स्थानीय वर्ग (या तब नामित या अनाम) शाब्दिक रूप से संलग्न कक्षाओं में नामों का उल्लेख कर सकता है। या शाब्दिक रूप से संलग्न विधि में केवल-पढ़ने के लिए चर ( <code>final</code> के रूप में चिह्नित) का उल्लेख कर सकता है।
  class CalculationWindow extends JFrame {


<वाक्यविन्यास प्रकाश लैंग = सी>
    private volatile int result;
#सम्मिलित <stdio.h>
    // ...
    public void calculateInSeparateThread(final URI uri) {
        // The expression "new Runnable() { ... }" is an anonymous class implementing the 'Runnable' interface.
        new Thread(
            new Runnable() {
                void run() {
                    // It can read final local variables:
                    calculate(uri);
                    // It can access private fields of the enclosing class:
                    result = result + 10;
                }
            }
        ).start();
    }
}
<code>final</code>  चरों को अधिकृत करने से आप चरों के मान अनुसार अधिकृत कर सकते है। यदि आप जिस चर को अधिकृत करना चाहते हैं वह गैर- <code>final</code> है आप हमेशा कक्षा के ठीक पूर्व अस्थायी अंतिम चर में कॉपी कर सकते हैं।


पूर्णांक मुख्य (शून्य) {
संदर्भ द्वारा चरो को अधिकृत करना परिवर्तनशील कंटेनर का संदर्भ के <code>final</code> संदर्भ का उपयोग करके अनुकरण किया जा सकता है। उदाहरण के लिए, एकल-तत्व सरणी स्थानीय वर्ग स्वयं कंटेनर संदर्भ के मूल्य को परिवर्तित करने में सक्षम नहीं होगा, किन्तु यह कंटेनर की सामग्री को परिवर्तितने में सक्षम होता है।
  टाइपपीफ इंट (*fn_int_to_int)(int); // फ़ंक्शन का प्रकार int->int
 
  fn_int_to_int योजक (पूर्णांक संख्या) {
  इंट ऐड (इंट वैल्यू) { रिटर्न वैल्यू + नंबर; }
  वापसी जोड़ें;
  }
 
  fn_int_to_int add10 = योजक (10);
  प्रिंटफ (% डी \ n, 10 (1) जोड़ें);
  वापसी 0;
}
</वाक्यविन्यास हाइलाइट>
 
यदि इसे क्रियान्वित किया जाता है तो यह अब प्रिंट करता है <code>11</code> आशा के अनुसार।
 
=== स्थानीय वर्ग और लैम्ब्डा फ़ंक्शंस (जावा) ===
[[जावा (प्रोग्रामिंग भाषा)]] [[क्लास (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)]] को [[विधि (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)]] के अंदर परिभाषित करने में सक्षम बनाता है। इन्हें स्थानीय वर्ग कहा जाता है। जब ऐसी कक्षाओं का नाम नहीं दिया जाता है, तो उन्हें [[अनाम वर्ग]] (या अनाम आंतरिक वर्ग) के रूप में जाना जाता है। स्थानीय वर्ग (या तो नामित या अनाम) लेक्सिक रूप से संलग्न कक्षाओं में नामों का उल्लेख कर सकता है, या केवल-पढ़ने के लिए चर (के रूप में चिह्नित) <code>final</code>) शाब्दिक रूप से संलग्न विधि में।
 
<वाक्यविन्यास प्रकाश लैंग = जावा>
वर्ग गणनाविंडो JFrame का विस्तार करता है {
  निजी अस्थिर इंट परिणाम;
  // ...
  सार्वजनिक शून्य गणना अलग-अलग थ्रेड (अंतिम यूआरआई यूरी) {
  // अभिव्यक्ति नया रननेबल () {...} 'रननेबल' इंटरफ़ेस को प्रयुक्त करने वाला अनाम वर्ग है।
  नया सूत्र(
  नया रननेबल () {
  शून्य रन () {
  // यह अंतिम स्थानीय चर पढ़ सकता है:
  गणना (यूरी);
  // यह संलग्न वर्ग के निजी क्षेत्रों तक पहुँच सकता है:
  परिणाम = परिणाम + 10;
  }
  }
  )।प्रारंभ करना();
  }
}
</वाक्यविन्यास हाइलाइट>
 
का कब्जा <code>final</code> वेरिएबल्स आपको वैल्यू द्वारा वेरिएबल्स को कैप्चर करने में सक्षम बनाता है। यदि आप जिस चर को कैप्चर करना चाहते हैं वह गैर-<code>final</code>, आप इसे हमेशा अस्थायी में कॉपी कर सकते हैं <code>final</code> कक्षा से ठीक पहले परिवर्तनशील।
 
रेफरेंस द्वारा वेरिएबल्स को कैप्चर करने का उपयोग करके अनुकरण किया जा सकता है <code>final</code> परिवर्तनशील कंटेनर का संदर्भ, उदाहरण के लिए, एकल-तत्व सरणी। स्थानीय वर्ग स्वयं कंटेनर संदर्भ के मूल्य को बदलने में सक्षम नहीं होगा, किन्तु यह कंटेनर की सामग्री को बदलने में सक्षम होगा।


जावा 8 के लैम्ब्डा भावों के आगमन के साथ,<ref>{{cite web
जावा 8 के लैम्ब्डा भावों के आगमन के साथ,<ref>{{cite web
| url =http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
| url =http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
| title = Lambda Expressions (The Java Tutorials)
| title = Lambda Expressions (The Java Tutorials)
}}</ref> क्लोजर उपरोक्त कोड को इस प्रकार निष्पादित करने का कारण बनता है:
}}</ref> क्लोजर के कारण उपरोक्त कोड को निष्पादित कर सकता है।
 
class CalculationWindow extends JFrame {
<वाक्यविन्यास प्रकाश लैंग = जावा>
    private volatile int result;
वर्ग गणनाविंडो JFrame का विस्तार करता है {
    // ...
  निजी अस्थिर इंट परिणाम;
    public void calculateInSeparateThread(final URI uri) {
  // ...
        // The code () -> { /* code */ } is a closure.
  सार्वजनिक शून्य गणना अलग-अलग थ्रेड (अंतिम यूआरआई यूरी) {
        new Thread(() -> {
  // कोड () -> { /* कोड */} क्लोजर है।
            calculate(uri);
  नया थ्रेड (() -> {
            result = result + 10;
  गणना (यूरी);
        }).start();
  परिणाम = परिणाम + 10;
    }
  })।प्रारंभ करना();
स्थानीय वर्ग प्रकार के आंतरिक वर्ग हैं जो विधि के शरीर के अंदर घोषित किए जाते हैं। जावा आंतरिक कक्षाओं का भी समर्थन करता है जिन्हें संलग्न वर्ग के गैर-स्थैतिक सदस्यों के रूप में घोषित किया जाता है।<ref>{{cite web
  }
}
</वाक्यविन्यास हाइलाइट>
 
स्थानीय वर्ग प्रकार के आंतरिक वर्ग हैं जो विधि के शरीर के भीतर घोषित किए जाते हैं। जावा आंतरिक कक्षाओं का भी समर्थन करता है जिन्हें संलग्न वर्ग के गैर-स्थैतिक सदस्यों के रूप में घोषित किया जाता है।<ref>{{cite web
| url = https://blogs.oracle.com/darcy/entry/nested_inner_member_and_top
| url = https://blogs.oracle.com/darcy/entry/nested_inner_member_and_top
| title = Nested, Inner, Member, and Top-Level Classes}}</ref> उन्हें सामान्यतः आंतरिक कक्षाओं के रूप में संदर्भित किया जाता है।<ref>{{cite web
| title = Nested, Inner, Member, and Top-Level Classes}}</ref> उन्हें सामान्यतः आंतरिक कक्षाओं के रूप में संदर्भित किया जाता है।<ref>{{cite web
| url = http://java.sun.com/docs/books/tutorial/java/javaOO/innerclasses.html
| url = http://java.sun.com/docs/books/tutorial/java/javaOO/innerclasses.html
| title = Inner Class Example (The Java Tutorials &gt; Learning the Java Language &gt; Classes and Objects)
| title = Inner Class Example (The Java Tutorials &gt; Learning the Java Language &gt; Classes and Objects)
}}</ref> इन्हें संलग्न वर्ग के शरीर में परिभाषित किया गया है और संलग्न वर्ग के आवृत्ति चरों तक पूर्ण पहुंच है। इन इंस्टेंस वेरिएबल्स के लिए उनके बंधन के कारण, विशेष सिंटैक्स का उपयोग करके संलग्न वर्ग के उदाहरण के लिए स्पष्ट बंधन के साथ आंतरिक वर्ग को केवल तत्काल किया जा सकता है।<ref>{{cite web
}}</ref> इन्हें संलग्न वर्ग के शरीर में परिभाषित किया गया है और संलग्न वर्ग के आवृत्ति चरों तक पूर्ण पहुंच है। इन इंस्टेंस चरों के लिए उनके बंधन के कारण, विशेष वाक्य - विन्यास का उपयोग करके संलग्न वर्ग के उदाहरण के लिए स्पष्ट बंधन के साथ आंतरिक वर्ग को केवल तत्काल किया जा सकता है।<ref>{{cite web
| url = http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html
| url = http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html
| title = Nested Classes (The Java Tutorials &gt; Learning the Java Language &gt; Classes and Objects)
| title = Nested Classes (The Java Tutorials &gt; Learning the Java Language &gt; Classes and Objects)
}}</ref>
}}</ref>
<वाक्यविन्यास प्रकाश लैंग = जावा>
public class EnclosingClass {
पब्लिक क्लास एनक्लोजिंग क्लास {
    /* Define the inner class */
  / * आंतरिक वर्ग को परिभाषित करें * /
    public class InnerClass {
  पब्लिक क्लास इनरक्लास {
        public int incrementAndReturnCounter() {
  सार्वजनिक पूर्णांक वृद्धि और रिटर्न काउंटर () {
            return counter++;
  वापसी काउंटर ++;
        }
  }
    }
  }
    private int counter;
    {
        counter = 0;
    }
    public int getCounter() {
        return counter;
    }
    public static void main(String[] args) {
        EnclosingClass enclosingClassInstance = new EnclosingClass();
        /* Instantiate the inner class, with binding to the instance */
        EnclosingClass.InnerClass innerClassInstance =
            enclosingClassInstance.new InnerClass();
        for (int i = enclosingClassInstance.getCounter();
              (i = innerClassInstance.incrementAndReturnCounter()) < 10;
              /* increment step omitted */) {
            System.out.println(i);
        }
    }
}


  निजी इंट काउंटर;
निष्पादन पर, यह 0 से 9 तक के पूर्णांकों को मुद्रण करना करता है। इस प्रकार के वर्ग को स्थिर वर्ग के साथ भ्रमित न करने के लिए सावधान रहते है, जो उसी प्रकार से घोषित किया जाता है जैसे स्थैतिक संशोधक के उपयोग के साथ किया जाता है। उनका वांछित प्रभाव नहीं है, बल्कि केवल वह वर्ग हैं जिनके समीप संलग्न वर्ग में परिभाषित कोई विशेष बंधन नहीं है।
  {
  काउंटर = 0;
  }


  सार्वजनिक int getCounter () {
जावा संस्करण इतिहास जावा_8 के रूप में, जावा प्रथम श्रेणी की वस्तुओं के रूप में फंक्शन का समर्थन करता है। इस रूप के लैम्ब्डा भावों को <code>Function<T,U></code> प्रकार का माना जाता है। जहां टी डोमेन है और यू छवि प्रकार है। व्यंजक को इसके <code>.apply(T t)</code> विधि से कॉल किया जा सकता है। किन्तु मानक विधि कॉल के साथ नहीं किया जाता है।
  वापसी काउंटर;
public static void main(String[] args) {
  }
    Function<String, Integer> length = s -> s.length();
    System.out.println( length.apply("Hello, world!") ); // Will print 13.


  सार्वजनिक स्थैतिक शून्य main (String [] args) {
=== ब्लॉक (सी, सी ++, वस्तुिव-सी 2.0) ===
  EnclosingClass enclosingClassInstance = new EnclosingClass();
  / * उदाहरण के लिए बाध्यकारी के साथ आंतरिक वर्ग को तुरंत चालू करें */
  EnclosingClass.InnerClass innerClassInstance =
  enclosingClassInstance.new InnerClass();
 
  for (int i = enclosingClassInstance.getCounter();
  (i = innerClassInstance.incrementAndReturnCounter ()) <10;
  /* इंक्रीमेंट चरण छोड़ा गया */) {
  System.out.println (i);
  }
  }
}
</वाक्यविन्यास हाइलाइट>
 
निष्पादन पर, यह 0 से 9 तक के पूर्णांकों को प्रिंट करेगा। इस प्रकार के वर्ग को नेस्टेड वर्ग के साथ भ्रमित न करने के लिए सावधान रहें, जो उसी तरह से घोषित किया जाता है जैसे स्थैतिक संशोधक के उपयोग के साथ; उनका वांछित प्रभाव नहीं है, बल्कि केवल वे वर्ग हैं जिनके पास संलग्न वर्ग में परिभाषित कोई विशेष बंधन नहीं है।
 
जावा संस्करण इतिहास#Java_8 के रूप में, जावा प्रथम श्रेणी की वस्तुओं के रूप में कार्यों का समर्थन करता है। इस रूप के लैम्ब्डा भावों को प्रकार का माना जाता है <code>Function<T,U></code> जहां T डोमेन है और U छवि प्रकार है। इसके साथ व्यंजक कहा जा सकता है <code>.apply(T t)</code> विधि, किन्तु मानक विधि कॉल के साथ नहीं।
 
<वाक्यविन्यास प्रकाश लैंग = जावा>
सार्वजनिक स्थैतिक शून्य main (String [] args) {
  समारोह <स्ट्रिंग, पूर्णांक> लंबाई = s -> s.length ();
 
  System.out.println (लंबाई। प्रयुक्त करें (हैलो, दुनिया!)); // 13 प्रिंट करेगा।
}
</वाक्यविन्यास हाइलाइट>
 
=== ब्लॉक (सी, सी ++, ऑब्जेक्टिव-सी 2.0) ===
{{Main|ब्लॉक (सी भाषा विस्तार)}}
{{Main|ब्लॉक (सी भाषा विस्तार)}}
Apple Inc. ने C (प्रोग्रामिंग भाषा), [[C++]], ऑब्जेक्टिव-C 2.0 और Mac OS X स्नो लेपर्ड | Mac OS X 10.6 स्नो लेपर्ड और IOS ( सेब) | आईओएस 4.0। ऐप्पल ने जीसीसी और क्लैंग कंपाइलर्स के लिए अपना कार्यान्वयन उपलब्ध कराया।
ऐप्पल ने सी, सी ++, वस्तुिव-सी 2.0 और मैक ओएस एक्स 10.6 "स्नो लेपर्ड" और आईओएस 4.0 में गैर-मानक विस्तार के रूप में ब्लॉक, क्लोजर के रूप प्रस्तुत किया जाता है। ऐप्पल ने जीसीसी और क्लैंग कंपाइलर्स के लिए अपना कार्यान्वयन उपलब्ध कराया है।


शाब्दिक ब्लॉक और ब्लॉक करने के लिए पॉइंटर्स को चिह्नित किया गया है <code>^</code>. जब ब्लॉक बनाया जाता है तो सामान्य स्थानीय चर मूल्य द्वारा कब्जा कर लिया जाता है, और केवल पढ़ने के लिए ब्लॉक के अंदर होता है। संदर्भ द्वारा कैप्चर किए जाने वाले वेरिएबल्स को चिह्नित किया गया है <code>__block</code>. जिन ब्लॉकों को उनके द्वारा बनाए गए चक्र से बाहर बने रहने की आवश्यकता है, उन्हें कॉपी करने की आवश्यकता हो सकती है।<ref>{{cite web|url=https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html|title=Blocks Programming Topics|author=Apple Inc.|access-date=2011-03-08}}</ref><ref>{{cite web|url=http://thirdcog.eu/pwcblocks/|title=Programming with C Blocks on Apple Devices|author=Joachim Bengtsson|date=7 July 2010|access-date=2010-09-18|archive-url=https://web.archive.org/web/20101025034928/http://thirdcog.eu/pwcblocks/|archive-date=25 October 2010|url-status=dead}}</ref>
शाब्दिक ब्लॉक और ब्लॉक करने के लिए सूचक को चिह्नित किया गया है। <code>^</code> ब्लॉक बनाया जाता है। तब सामान्य स्थानीय चर मूल्य द्वारा कब्जा कर लिया जाता है और केवल पढ़ने के लिए ब्लॉक के अंदर होता है। संदर्भ द्वारा अधिकृत किए जाने वाले चरों को <code>__block</code> चिह्नित किया गया है। जिन ब्लॉकों को उनके द्वारा बनाए गए क्षेत्र से बाहर बने रहने की आवश्यकता है। उन्हें कॉपी करने की आवश्यकता हो सकती है।<ref>{{cite web|url=https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html|title=Blocks Programming Topics|author=Apple Inc.|access-date=2011-03-08}}</ref><ref>{{cite web|url=http://thirdcog.eu/pwcblocks/|title=Programming with C Blocks on Apple Devices|author=Joachim Bengtsson|date=7 July 2010|access-date=2010-09-18|archive-url=https://web.archive.org/web/20101025034928/http://thirdcog.eu/pwcblocks/|archive-date=25 October 2010|url-status=dead}}</ref>
<वाक्यविन्यास हाइलाइट लैंग = ओबीजेसी>
टाइपपीफ इंट (^ इंटब्लॉक) ();


इंटब्लॉक डाउनकाउंटर (इंट स्टार्ट) {
typedef int (^IntBlock)();
__ ब्लॉक इंट आई = स्टार्ट;
वापसी ^ इंट () {
वापसी मैं--;
} कॉपी] ऑटोरिलीज];
}


इंटब्लॉक एफ = डाउनकाउंटर (5);
IntBlock downCounter(int start) { __block int i = start; return [[ ^int() { return i--; } copy] autorelease]; }
एनएसएलओजी (@% डी, एफ ());
एनएसएलओजी (@% डी, एफ ());
एनएसएलओजी (@% डी, एफ ());
</वाक्यविन्यास हाइलाइट>


IntBlock f = downCounter(5); NSLog(@"%d", f()); NSLog(@"%d", f()); NSLog(@"%d", f());
=== प्रतिनिधि (सी #, वीबी.नेट, डी) ===
=== प्रतिनिधि (सी #, वीबी.नेट, डी) ===
सी शार्प (प्रोग्रामिंग लैंग्वेज) | सी # अनाम तरीके और लैम्ब्डा एक्सप्रेशन क्लोजर का समर्थन करते हैं:
सी शार्प (प्रोग्रामिंग भाषा) | सी # अनाम विधि और लैम्ब्डा अभिव्यक्ति क्लोजर का समर्थन करते हैं।
var data = new[] {1, 2, 3, 4};
var multiplier = 2; 
मूल दृश्य .नेट, जिसमें सी# के समान अनेक भाषा सुविधाएँ हैं, क्लोजर के साथ लैम्ब्डा अभिव्यक्ति का भी समर्थन करता है।


<वाक्यविन्यास प्रकाश लैंग = csharp>
Dim data = {1, 2, 3, 4}
var डेटा = नया [] {1, 2, 3, 4};
Dim multiplier = 2
वार गुणक = 2;
Dim result = data.Select(Function(x) x * multiplier)
var परिणाम = डेटा। चयन करें (x => x * गुणक);
डी (प्रोग्रामिंग भाषा) में, क्लोजर को डेलीगेट्स द्वारा प्रयुक्त किया जाता है। फंक्शन सूचक को कॉन्टेक्स्ट सूचक के साथ जोड़ा जाता है। (उदाहरण के लिए कक्षाये इंस्टेंस, या क्लोजर के स्थितियों में संचय पर समुदाय फ्रेम)।
</वाक्यविन्यास हाइलाइट>
auto test1() {
    int a = 7;
    return delegate() { return a + 3; }; // anonymous delegate construction
}
auto test2() {
    int a = 20;
    int foo() { return a + 5; } // inner function
    return &foo;  // other way to construct delegate
}
void bar() {
    auto dg = test1();
    dg();    // =10  // ok, test1.a is in a closure and still exists
    dg = test2();
    dg();    // =25  // ok, test2.a is in a closure and still exists
}
डी संस्करण 1 में सीमित क्लोजर समर्थन है। उदाहरण के लिए, उपरोक्त कोड सही रूप से कार्य नहीं करता है, चूंकि चर ए समुदाय पर है, और परीक्षण () से लौटने के पश्चात्, यह अब इसका उपयोग करने के लिए मान्य नहीं है। (संभवतः डीजी () के माध्यम से फू को कॉल करना, 'वापसी करेगा यादृच्छिक 'पूर्णांक)। इसे ढेर पर चर 'ए' को स्पष्ट रूप से आवंटित करके, या सभी आवश्यक क्लोजर चरों को संग्रहीत करने के लिए संरचनाएं या कक्षाओ का उपयोग करके हल किया जा सकता है और उसी कोड को प्रयुक्त करने वाली विधि से प्रतिनिधि का निर्माण किया जा सकता है। क्लोजर को अन्य फंक्शन में पारित किया जा सकता है, जब तक कि वह केवल तब तक उपयोग किए जाते हैं जब संदर्भित मान अभी भी मान्य होते हैं (उदाहरण के लिए कॉलबैक पैरामीटर के रूप में क्लोजर के साथ किसी अन्य फंक्शन को कॉल करना), और सामान्य डेटा प्रोसेसिंग कोड लिखने के लिए उपयोगी होते हैं। अतः यह सीमा, व्यवहार में, अधिकांशतः कोई समस्या नहीं होती है।


Visual Basic .NET, जिसमें C# के समान कई भाषा सुविधाएँ हैं, क्लोजर के साथ लैम्ब्डा एक्सप्रेशन का भी समर्थन करता है:
यह सीमा डी संस्करण 2 में तय की गई थी। चर 'ए' स्वचालित रूप से संचय पर आवंटित किया जाएगा चूंकि इसका उपयोग आंतरिक फंक्शन में किया जाता है और उस फंक्शन का प्रतिनिधि वर्तमान क्षेत्र से बच सकता है। (डीजी या वापसी के लिए नियुक्त मेंट के माध्यम से)। कोई भी अन्य स्थानीय चर (या तर्क) जो प्रतिनिधियों द्वारा संदर्भित नहीं हैं या जो केवल प्रतिनिधियों द्वारा संदर्भित हैं जो वर्तमान क्षेत्र से बाहर नहीं निकलते हैं।समुदाय पर बने रहते हैं, जो संचय आवंटन की तुलना में सरल और तेज़ है। आंतरिक वर्ग विधियों के लिए भी यही सच है जो किसी फंक्शन के चर को संदर्भित करता है।


<वाक्यविन्यास लैंग = vb.net>
=== फंक्शन वस्तु्स (सी ++) ===
मंद डेटा = {1, 2, 3, 4}
सी ++ ओवरलोडिंग द्वारा समारोह वस्तुओ को परिभाषित करने में सक्षम बनाता है <code>operator()</code>. ये वस्तु कुछ सीमा तक कार्यात्मक प्रोग्रामिंग भाषा में कार्यों की भांति व्यवहार करते हैं। वे क्रम पर बनाए जा सकते हैं और इसमें राज्य सम्मिलित हो सकते हैं, लेकिन वे स्थानीय चर को बंद करने के रूप में निहित रूप से अधिकृत नहीं करते हैं। [[सी ++ 11]] के अनुसार, सी ++ भाषा भी क्लोजर का समर्थन करती है, जो एक प्रकार का समारोह वस्तु है जो लैम्ब्डा-एक्सप्रेशन नामक एक विशेष भाषा निर्माण से स्वचालित रूप से निर्मित होता है। एक सी ++ क्लोजर क्लोजर वस्तु या संदर्भ के सदस्यों के रूप में एक्सेस किए गए चर की प्रतियों को संग्रहीत करके इसके संदर्भ को अधिकृत कर सकता है। इस स्थिति में, यदि क्लोजर वस्तु संदर्भित वस्तु के सीमा से बाहर निकलता है, तो इसका आह्वान करता है <code>operator()</code> अपरिभाषित व्यवहार का कारण बनता है क्योंकि सी ++ क्लोजर उनके संदर्भ के जीवनकाल का विस्तार नहीं करते हैं।{{main|अनाम कार्य # सी ++ (सी ++ 11 के बाद से)}}
मंद गुणक = 2
मंद परिणाम = डेटा। चयन करें (फ़ंक्शन (x) x * गुणक)
</वाक्यविन्यास हाइलाइट>


डी (प्रोग्रामिंग लैंग्वेज) में, क्लोजर को डेलीगेट्स द्वारा प्रयुक्त किया जाता है, फंक्शन पॉइंटर को कॉन्टेक्स्ट पॉइंटर के साथ जोड़ा जाता है (उदाहरण के लिए क्लास इंस्टेंस, या क्लोजर के स्थितियों में हीप पर स्टैक फ्रेम)
शून्य फू (स्ट्रिंग मायनाम) {
 
void foo(string myname) {
<वाक्यविन्यास प्रकाश लैंग = डी>
    int y;
ऑटो टेस्ट 1 () {
    vector<string> n;
  इंट ए = 7;
    // ...
  वापसी प्रतिनिधि () {वापसी + 3; }; // अनाम प्रतिनिधि निर्माण
    auto i = std::find_if(n.begin(), n.end(),
                // this is the lambda expression:
                [&](const string& s) { return s != myname && s.size() > y; }
              );
    // 'i' is now either 'n.end()' or points to the first string in 'n'
    // which is not equal to 'myname' and whose length is greater than 'y'
}
}


ऑटो टेस्ट 2 () {
=== इनलाइन एजेंट (एफिल) ===
  इंट ए = 20;
एफिल (प्रोग्रामिंग भाषा) में क्लोजर को परिभाषित करने वाले इनलाइन एजेंट सम्मिलित हैं। इनलाइन एजेंट रूटीन का प्रतिनिधित्व करने वाली वस्तु है। जिसे रूटीन इन-लाइन का कोड देकर परिभाषित किया जाता है। उदाहरण के लिए, में
  इंट फू () {वापसी ए + 5; } // आंतरिक कार्य
  वापसी और फू; // प्रतिनिधि बनाने का दूसरा विधि
}


शून्य बार () {
ok_button.click_event.subscribe (
  ऑटो डीजी = test1 ();
  डीजी (); // = 10 // ठीक है, test1.a क्लोजर में है और अभी भी उपस्तिथ है


  डीजी = test2 ();
agent (x, y: INTEGER) do
  डीजी (); // = 25 // ठीक है, test2.a बंद होने की स्थिति में है और अभी भी उपस्तिथ है
}
</वाक्यविन्यास हाइलाइट>


D संस्करण 1 में सीमित क्लोजर समर्थन है। उदाहरण के लिए, उपरोक्त कोड सही ढंग से काम नहीं करेगा, क्योंकि चर a स्टैक पर है, और परीक्षण () से लौटने के बाद, यह अब इसका उपयोग करने के लिए मान्य नहीं है (संभवतः डीजी () के माध्यम से फू को कॉल करना, 'वापसी करेगा यादृच्छिक 'पूर्णांक)। इसे ढेर पर चर 'ए' को स्पष्ट रूप से आवंटित करके, या सभी आवश्यक बंद चरों को संग्रहीत करने के लिए स्ट्रक्चर्स या क्लास का उपयोग करके हल किया जा सकता है और उसी कोड को प्रयुक्त करने वाली विधि से प्रतिनिधि का निर्माण किया जा सकता है। क्लोजर को अन्य कार्यों में पारित किया जा सकता है, जब तक कि वे केवल तब तक उपयोग किए जाते हैं जब संदर्भित मान अभी भी मान्य होते हैं (उदाहरण के लिए कॉलबैक पैरामीटर के रूप में क्लोजर के साथ किसी अन्य फ़ंक्शन को कॉल करना), और सामान्य डेटा प्रोसेसिंग कोड लिखने के लिए उपयोगी होते हैं, इसलिए यह सीमा , व्यवहार में, अधिकांशतः कोई समस्या नहीं होती है।
map.country_at_coordinates (x, y).display


यह सीमा डी संस्करण 2 में तय की गई थी - चर 'ए' स्वचालित रूप से हीप पर आवंटित किया जाएगा क्योंकि इसका उपयोग आंतरिक फ़ंक्शन में किया जाता है, और उस फ़ंक्शन का प्रतिनिधि वर्तमान चक्र से बच सकता है (डीजी या वापसी के लिए असाइनमेंट के माध्यम से)। कोई भी अन्य स्थानीय चर (या तर्क) जो प्रतिनिधियों द्वारा संदर्भित नहीं हैं या जो केवल प्रतिनिधियों द्वारा संदर्भित हैं जो वर्तमान चक्र से बाहर नहीं निकलते हैं, स्टैक पर बने रहते हैं, जो हीप आवंटन की तुलना में सरल और तेज़ है। आंतरिक वर्ग विधियों के लिए भी यही सच है जो किसी फ़ंक्शन के चर को संदर्भित करता है।
end


=== फ़ंक्शन ऑब्जेक्ट्स (सी ++) ===
)
सी ++ ओवरलोडिंग द्वारा फ़ंक्शन ऑब्जेक्ट्स को परिभाषित करने में सक्षम बनाता है <code>operator()</code>. ये ऑब्जेक्ट कुछ हद तक कार्यात्मक प्रोग्रामिंग भाषा में कार्यों की तरह व्यवहार करते हैं। वे रनटाइम पर बनाए जा सकते हैं और इसमें राज्य शामिल हो सकते हैं, लेकिन वे स्थानीय चर को बंद करने के रूप में निहित रूप से कैप्चर नहीं करते हैं। [[सी ++ 11]] के अनुसार, सी ++ भाषा भी क्लोजर का समर्थन करती है, जो एक प्रकार का फ़ंक्शन ऑब्जेक्ट है जो लैम्ब्डा-एक्सप्रेशन नामक एक विशेष भाषा निर्माण से स्वचालित रूप से निर्मित होता है। एक सी ++ क्लोजर क्लोजर ऑब्जेक्ट या संदर्भ के सदस्यों के रूप में एक्सेस किए गए चर की प्रतियों को संग्रहीत करके इसके संदर्भ को कैप्चर कर सकता है। बाद के मामले में, यदि क्लोजर ऑब्जेक्ट संदर्भित ऑब्जेक्ट के दायरे से बाहर निकलता है, तो इसका आह्वान करता है <code>operator()</code> अपरिभाषित व्यवहार का कारण बनता है क्योंकि सी ++ क्लोजर उनके संदर्भ के जीवनकाल का विस्तार नहीं करते हैं।{{main|Anonymous function#C++ (since C++11)}}
<वाक्यविन्यास लैंग = सीपीपी>
शून्य फू (स्ट्रिंग मायनाम) {
  इंट वाई;
  वेक्टर <स्ट्रिंग> एन;
  // ...
  ऑटो मैं = एसटीडी::find_if(n.begin(), n.end(),
  // यह लैम्ब्डा अभिव्यक्ति है:
  [&] (स्थिरांक स्ट्रिंग और s) {वापसी s! = myname && s.size ()> y; }
  );
  // 'i' अब या तो 'n.end ()' है या 'n' में पहले स्ट्रिंग को इंगित करता है
  // जो 'myname' के बराबर नहीं है और जिसकी लंबाई 'y' से अधिक है
}
</वाक्यविन्यास हाइलाइट>
 
=== इनलाइन एजेंट (एफिल) ===
एफिल (प्रोग्रामिंग लैंग्वेज) में क्लोजर को परिभाषित करने वाले इनलाइन एजेंट सम्मिलित हैं। इनलाइन एजेंट रूटीन का प्रतिनिधित्व करने वाली वस्तु है, जिसे रूटीन इन-लाइन का कोड देकर परिभाषित किया जाता है। उदाहरण के लिए, में


<वाक्यविन्यास लैंग = एफिल>
सदस्यता लेने का तर्क <code>subscribe</code>एजेंट है। जो दो तर्कों के साथ प्रक्रिया का प्रतिनिधित्व करता है। प्रक्रिया देश को संबंधित निर्देशांक पर ढूंढती है और इसे <code>click_event</code> के लिए प्रदर्शित करती है। पूरे एजेंट को ईवेंट प्रकार की सदस्यता दी गई है।
ok_button.click_event.subscribe (
एजेंट (x, y: INTEGER) करते हैं
map.country_at_coordinates (x, y).प्रदर्शन
अंत
)
</वाक्यविन्यास हाइलाइट>


को तर्क <code>subscribe</code> एजेंट है, जो दो तर्कों के साथ प्रक्रिया का प्रतिनिधित्व करता है; प्रक्रिया देश को संबंधित निर्देशांक पर ढूंढती है और इसे प्रदर्शित करती है। पूरे एजेंट को ईवेंट प्रकार की सदस्यता दी गई है <code>click_event</code> के लिए
निश्चित बटन, जिससे कि जब भी उस बटन पर घटना प्रकार का उदाहरण होता है। चूंकि उपयोगकर्ता ने बटन पर क्लिक किया है। <code>x</code> और <code>y</code>प्रक्रिया को माउस निर्देशांक के साथ तर्क के रूप में पारित किया जाता है।
निश्चित बटन, जिससे कि जब भी उस बटन पर घटना प्रकार का उदाहरण हो - क्योंकि उपयोगकर्ता ने बटन पर क्लिक किया है - प्रक्रिया को माउस निर्देशांक के साथ तर्क के रूप में पारित किया जाएगा <code>x</code> और <code>y</code>.


एफिल एजेंटों की मुख्य सीमा, जो उन्हें अन्य भाषाओं में बंद होने से अलग करती है, यह है कि वे स्थानीय चर को संलग्न चक्र से संदर्भित नहीं कर सकते हैं। यह डिज़ाइन निर्णय अस्पष्टता से बचने में मदद करता है जब क्लोजर में स्थानीय चर मान के बारे में बात की जाती है - क्या यह चर का नवीनतम मान होना चाहिए या एजेंट के बनाए जाने पर कैप्चर किया गया मान होना चाहिए? केवल <code>Current</code> (वर्तमान वस्तु का संदर्भ, के अनुरूप <code>this</code> जावा में), इसकी विशेषताओं और एजेंट के तर्कों को एजेंट निकाय के भीतर से ही एक्सेस किया जा सकता है। एजेंट को अतिरिक्त बंद ऑपरेंड प्रदान करके बाहरी स्थानीय चर के मान पारित किए जा सकते हैं।
एफिल एजेंटों की मुख्य सीमा, जो उन्हें अन्य भाषाओं में क्लोजर होने से भिन्न करती है। यह है कि वह स्थानीय चर को संलग्न क्षेत्र से संदर्भित नहीं कर सकते हैं। यह डिज़ाइन निर्णय अस्पष्टता से बचने में मदद करता है। जब क्लोजर में स्थानीय चर मान के बारे में बात की जाती है। क्या यह चर का नवीनतम मान होना चाहिए या एजेंट के बनाए जाने पर अधिकृत किया गया मान होना चाहिए? केवल <code>Current</code> (वर्तमान वस्तु का संदर्भ, के अनुरूप <code>this</code> जावा में), इसकी विशेषताओं और एजेंट के तर्कों को एजेंट निकाय के अंदर से ही अनुलेख किया जा सकता है। एजेंट को अतिरिक्त क्लोजर ऑपरेंड प्रदान करके बाहरी स्थानीय चर के मान पारित किए जा सकते हैं।


=== सी ++ बिल्डर क्लोजर आरक्षित शब्द ===
=== सी ++ बिल्डर क्लोजर आरक्षित शब्द ===
Embarcadero C++ Builder फ़ंक्शन पॉइंटर के समान सिंटैक्स वाली विधि को पॉइंटर प्रदान करने के लिए आरक्षित शब्द _ क्लोजर प्रदान करता है।<ref>Full documentation can be found at http://docwiki.embarcadero.com/RADStudio/Rio/en/Closure</ref>
एम्बरकाडेरो सी++ निर्माता फंक्शन सूचक के समान वाक्य - विन्यास वाली विधि को सूचक प्रदान करने के लिए आरक्षित शब्द _ क्लोजर प्रदान करता है।<ref>Full documentation can be found at http://docwiki.embarcadero.com/RADStudio/Rio/en/Closure</ref>
मानक C में आप a लिख सकते हैं {{mono|[[typedef]]}} निम्नलिखित सिंटैक्स का उपयोग करके फ़ंक्शन प्रकार के सूचक के लिए:<syntaxhighlight lang= c++ >
मानक सी में आप एलिख सकते हैं {{mono|[[टाइपपीफ]]}} निम्नलिखित वाक्य - विन्यास का उपयोग करके फंक्शन प्रकार के सूचक के लिए कार्य करता है।<syntaxhighlight lang="c++">
टाइपपीफ शून्य (*TMyFunctionPointer) (शून्य);
typedef void (*TMyFunctionPointer)( void );
</syntaxhighlight>इसी प्रकार से आप घोषित कर सकते हैं a {{mono|typedef}} निम्नलिखित सिंटैक्स का उपयोग करने वाली विधि के लिए सूचक के लिए:<nowiki><syntaxhighlight lang= c++ ></nowiki>
</syntaxhighlight>इसी प्रकार से आप घोषित कर सकते हैं ए टाइपपीफ निम्नलिखित वाक्य - विन्यास का उपयोग करने वाली विधि के लिए सूचक के लिए:<वाक्य - विन्यास प्रमुखता लंग= सी++ >
टाइपपीफ शून्य (__closure *TMyMethodPointer) ();
typedef void (__closure *TMyMethodPointer)();
</वाक्यविन्यास हाइलाइट>


== यह भी देखें ==
== यह भी देखें ==
* बेनामी समारोह
* बेनामी फंक्शन
* ब्लॉक (सी भाषा [[विस्तार]])
* ब्लॉक (सी भाषा [[विस्तार]])
* [[कमांड पैटर्न]]
* [[कमांड पैटर्न]]
Line 606: Line 523:
* आलसी मूल्यांकन
* आलसी मूल्यांकन
* [[आंशिक आवेदन]]
* [[आंशिक आवेदन]]
* स्पेगेटी स्टैक
* स्पेगेटी समुदाय
* [[सिंटैक्टिक क्लोजर]]
* [[सिंटैक्टिक क्लोजर]]
* [[मूल्य-स्तरीय प्रोग्रामिंग]]
* [[मूल्य-स्तरीय प्रोग्रामिंग]]
Line 619: Line 536:


== बाहरी संबंध ==
== बाहरी संबंध ==
*[https://web.archive.org/web/20160510140804/http://library.readscheme.org/page1.html Original "Lambda Papers"]: A classic series of papers by [[Guy Steele]] and [[Gerald Sussman]] discussing, among other things, the versatility of closures in the context of Scheme (where they appear as ''[[lambda calculus|lambda]] expressions'').
*[https://web.archive.org/web/20160510140804/http://library.readscheme.org/page1.html Original "लैम्ब्डा Papers"]: एclassic series of papers by [[Guy Steele]] and [[Gerald Sussman]] discussing, among other things, the versatility of closures in the context of Scheme (where they appear as ''[[lambda calculus|लैम्ब्डा]] expressions'').
* {{cite web
* {{cite web
| author = Neal Gafter
| author = Neal Gafter
Line 633: Line 550:
}}
}}
*[http://martinfowler.com/bliki/Closure.html Closures]: An article about closures in [[Dynamic typing|dynamically typed]] imperative languages, by [[Martin Fowler (software engineer)|Martin Fowler]].
*[http://martinfowler.com/bliki/Closure.html Closures]: An article about closures in [[Dynamic typing|dynamically typed]] imperative languages, by [[Martin Fowler (software engineer)|Martin Fowler]].
*[http://martinfowler.com/bliki/CollectionClosureMethod.html Collection closure methods]: An example of a technical domain where using closures is convenient, by Martin Fowler.
*[http://martinfowler.com/bliki/CollectionClosureMethod.html Collection closure methods]: An example of एtechnical doमुख्य where using closures is convenient, by Martin Fowler.
 
{{DEFAULTSORT:Closure (Computer Science)}}[[Category: प्रोग्रामिंग भाषा अवधारणाओं]] [[Category: कार्यात्मक प्रोग्रामिंग भाषाओं का कार्यान्वयन]] [[Category: सबरूटीन्स]] [[Category: लेख उदाहरण के साथ पायथन (प्रोग्रामिंग भाषा) कोड]] [[Category: स्कीम (प्रोग्रामिंग लैंग्वेज) कोड के उदाहरण वाले लेख]] [[Category: उदाहरण जावास्क्रिप्ट कोड वाले लेख]] [[Category: C++ कोड उदाहरण के साथ लेख]] [[Category: एफिल कोड उदाहरण के साथ लेख]] [[Category: सी शार्प कोड उदाहरण के साथ लेख]] [[Category: उदाहरण डी कोड वाले लेख]] [[Category: ऑब्जेक्टिव-सी कोड के उदाहरण वाले लेख]] [[Category: जावा कोड उदाहरण के साथ लेख]] [[Category: रूबी कोड उदाहरण के साथ लेख]] [[Category: स्मॉलटॉक कोड के उदाहरण वाले लेख]] [[Category: उदाहरण हास्केल कोड वाले लेख]]
 


{{DEFAULTSORT:Closure (Computer Science)}}


[[Category: Machine Translated Page]]
[[Category:Articles with hatnote templates targeting a nonexistent page|Closure (Computer Science)]]
[[Category:Created On 17/02/2023]]
[[Category:C++ कोड उदाहरण के साथ लेख|Closure (Computer Science)]]
[[Category:CS1 maint|Closure (Computer Science)]]
[[Category:Created On 17/02/2023|Closure (Computer Science)]]
[[Category:Lua-based templates|Closure (Computer Science)]]
[[Category:Machine Translated Page|Closure (Computer Science)]]
[[Category:Pages with script errors|Closure (Computer Science)]]
[[Category:Short description with empty Wikidata description|Closure (Computer Science)]]
[[Category:Templates Vigyan Ready|Closure (Computer Science)]]
[[Category:Templates that add a tracking category|Closure (Computer Science)]]
[[Category:Templates that generate short descriptions|Closure (Computer Science)]]
[[Category:Templates using TemplateData|Closure (Computer Science)]]
[[Category:उदाहरण जावास्क्रिप्ट कोड वाले लेख|Closure (Computer Science)]]
[[Category:उदाहरण डी कोड वाले लेख|Closure (Computer Science)]]
[[Category:उदाहरण हास्केल कोड वाले लेख|Closure (Computer Science)]]
[[Category:एफिल कोड उदाहरण के साथ लेख|Closure (Computer Science)]]
[[Category:ऑब्जेक्टिव-सी कोड के उदाहरण वाले लेख|Closure (Computer Science)]]
[[Category:कार्यात्मक प्रोग्रामिंग भाषाओं का कार्यान्वयन|Closure (Computer Science)]]
[[Category:जावा कोड उदाहरण के साथ लेख|Closure (Computer Science)]]
[[Category:प्रोग्रामिंग भाषा अवधारणाओं|Closure (Computer Science)]]
[[Category:रूबी कोड उदाहरण के साथ लेख|Closure (Computer Science)]]
[[Category:लेख उदाहरण के साथ पायथन (प्रोग्रामिंग भाषा) कोड|Closure (Computer Science)]]
[[Category:सबरूटीन्स|Closure (Computer Science)]]
[[Category:सी शार्प कोड उदाहरण के साथ लेख|Closure (Computer Science)]]
[[Category:स्कीम (प्रोग्रामिंग लैंग्वेज) कोड के उदाहरण वाले लेख|Closure (Computer Science)]]
[[Category:स्मॉलटॉक कोड के उदाहरण वाले लेख|Closure (Computer Science)]]

Latest revision as of 16:26, 13 April 2023

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

इतिहास और व्युत्पत्त

क्लोजर की अवधारणा को सन्न 1960 के दशक में λ-कैलकुलस में भावों के यांत्रिक मूल्यांकन के लिए विकसित किया गया था और प्रथम बार सन्न 1970 में पूर्ण प्रकार से आरपीएल प्रोग्रामिंग भाषा में भाषा सुविधा के रूप में प्रयुक्त किया गया था। जिससे कि शाब्दिक रूप से प्रथम श्रेणी के फंक्शन का समर्थन किया जा सकता था।[2]

पीटर जे. लैंडिन ने सन्न 1964 में सीमा क्लोजर को पर्यावरण भाग और नियंत्रण भाग के रूप में परिभाषित किया था। जैसा कि अभिव्यक्ति के मूल्यांकन के लिए उनकी एसईसीडी मशीन द्वारा उपयोग किया जाता है।[3] जोएल मोसेस ने लैम्ब्डा अभिव्यक्ति को संदर्भित करने के लिए क्लोजर शब्द की शुरुआत करने का श्रेय लैंडिन को दिया है। जिसके खुला बंधन (नि: शुल्क चरों) को शाब्दिक वातावरण द्वारा (या आंतरिक) क्लोजर कर दिया गया है। जिसके परिणामस्वरूप क्लोजर अभिव्यक्ति या क्लोजर होता है।[4][5] इस प्रयोग को पश्चात् में गेराल्ड जे सुस्मान और गाइ एल. स्टील, जूनियर द्वारा अपनाया गया था। जब उन्होंने सन्न 1975 में योजना (प्रोग्रामिंग भाषा) को परिभाषित किया था।[6] अतः लिस्प (प्रोग्रामिंग भाषा) का शाब्दिकी विस्तार रूपांतर और व्यापक हो गया है।

सुस्मान और हेरोल्ड एबेलसन भी सन्न 1980 के दशक में दूसरे असंबंधित अर्थ के साथ क्लोजर शब्द का उपयोग करते हैं। चूँकि ऑपरेटर की संपत्ति जो डेटा संरचना में डेटा जोड़ती है और स्थिर डेटा संरचनाओं को भी जोड़ने में सक्षम होती है। अतः यह शब्द का प्रयोग कंप्यूटर विज्ञान में पूर्व उपयोग के अतिरिक्त क्लोजर (गणित) से आता है। जिसे लेखक शब्दावली में इस ओवरलैप को "दुर्भाग्यपूर्ण" मानते हैं।[7]

अनाम कार्य

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

उदाहरण के लिए, निम्नलिखित पायथन (प्रोग्रामिंग भाषा) कोड में,

 def f(x):
    def g(y):
        return x + y
    return g  # Return a closure.

def h(x):
    return lambda y: x + y  # Return a closure.

# Assigning specific closures to variables.
a = f(1)
b = h(1)

# Using the closures stored in variables.
assert a(5) == 6
assert b(5) == 6

# Using closures without binding them to variables first.
assert f(1)(5) == 6  # f(1) is the closure.
assert h(1)(5) == 6  # h(1) is the closure.
  1. प्रथम चर से आबद्ध किए बिना क्लोजर का उपयोग करता है।

सामान्यतः a और b के मान क्लोजर होते है। जो दोनों स्थितियों में स्थिर फंक्शन को संलग्न फंक्शन से मुक्त चर के साथ वापस करके उत्पादित किया जाता है। जिससे कि मुक्त चर संलग्न फंक्शन के पैरामीटर x के मान से जुड़ जाता है। चूँकि a और b में क्लोजर कार्यात्मक रूप से समान हैं। कार्यान्वयन में एकमात्र अंतर यह है कि प्रथम स्थितियों में हमने नाम g के साथ स्थिर फंक्शन का उपयोग नाम के साथ किया था। (अज्ञात फंक्शन बनाने के लिए पाइथन संकेत शब्द lambda का उपयोग करके) उन्हें परिभाषित करने में यदि कोई मूल नाम प्रयुक्त होता है, वह अप्रासंगिक है।

क्लोजर किसी भी अन्य मान की भांति वह मान है। इसके चर को नियुक्त करने की आवश्यकता नहीं है और इसके अतिरिक्त इसे सीधे उपयोग किया जा सकता है। जैसा कि उदाहरण की अंतिम दो पंक्तियों में दिखाया गया है। इस उपयोग को अनाम क्लोजर माना जा सकता है।

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

अंत में, गैर-स्थानीय चर के क्षेत्र से बाहर होने पर क्लोजर केवल मुक्त चर वाले फंक्शन से प्रथक होता है। अन्यथा परिभाषित वातावरण और निष्पादन वातावरण से मेल खाते हैं और इन्हें प्रथक करने के लिए कुछ भी नहीं है। (स्थैतिक और गतिशील बाध्यकारी को प्रथक नहीं किया जा सकता है। जिससे कि नाम समान मानों को हल करते हैं।) उदाहरण के लिए, नीचे दिए गए प्रोग्राम में, मुक्त चर x (वैश्विक सीमा के साथ गैर-स्थानीय चर x के लिए बाध्य) वाले कार्यो को उसी वातावरण में निष्पादित किया जाता हैं। जहाँ x को परिभाषित किया गया है। अतः यह सारहीन है कि क्या ये वास्तव में क्लोजर हैं।

nums = [1, 2, 3]

def f(y):
    return x + y

map(f, nums)
map(lambda y: x + y, nums)

यह अधिकांशतः फंक्शन वापसी द्वारा प्राप्त किया जाता है। चूँकि फंक्शन को गैर-स्थानीय चर के क्षेत्र में परिभाषित किया जाना चाहिए। इस स्थितियों में सामान्यतः इसका क्षेत्र g छोटा होता है।

यह चर छायांकन (जो गैर-स्थानीय चर के क्षेत्र को कम करता है।) द्वारा भी प्राप्त किया जा सकता है। चूंकि व्यवहार में यह कम साधारण है। चूंकि यह कम उपयोगी है और छायांकन को हतोत्साहित किया जाता है। इस उदाहरण में f क्लोजर के रूप में देखा जा सकता है। जिससे कि f के शरीर में x वैश्विक नाम स्थान में x के लिए बाध्य है न कि x स्थानीय के लिए g होता है।

def f(y):
    return x + y

def g(z):
    x = 1  # local x shadows global x
    return f(z)


g(1)  # evaluates to 1, not 2

अनुप्रयोग

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

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

प्रथम श्रेणी के कार्य

क्लोजर सामान्यतः प्रथम श्रेणी के फंक्शन के साथ भाषाओं में दिखाई देते हैं। चूँकि दूसरे शब्दों में, ऐसी भाषाएं फंक्शन को तर्कों के रूप में पारित करने में सक्षम बनाती हैं। अतः फंक्शन कॉल से वापस आती हैं और चर नामों से बंधी होती हैं। साधारण रूप से जैसे शृंखला के प्रकार और पूर्णांक होते है। उदाहरण के लिए, निम्नलिखित योजना (प्रोग्रामिंग भाषा) फंक्शन पर विचार कर सकते है।

विक्रय गई कम से कम सीमा प्रतियों वाली सभी पुस्तकों की सूची लौटाएं।

(परिभाषित करें (सर्वाधिक विक्रय होने वाली पुस्तकों की सीमा)

; Return a list of all books with at least THRESHOLD copies sold.
(define (best-selling-books threshold)
  (filter
    (lambda (book)
      (>= (book-sales book) threshold))
 book-list))

इस उदाहरण में, लैम्ब्डा (प्रोग्रामिंग) (lambda (book) (>= (book-sales book) threshold)) best-selling-booksफंक्शन के अंदर दिखाई देता है जब लैम्ब्डा अभिव्यक्ति का मूल्यांकन किया जाता है। तब योजना लैम्ब्डा अभिव्यक्ति के लिए कोड और संदर्भ से मिलकर thresholdचर क्लोजर बनाती है। जो लैम्ब्डा अभिव्यक्ति के अंदर मुक्त चर है।

इसके पश्चात् क्लोजर को filter फंक्शन में भेज दिया जाता है। जो यह निर्धारित करने के लिए बार-बार कॉल करता है कि कौन सी पुस्तकें परिणाम सूची में जोड़ी जानी हैं और कौन सी छोड़ी जानी हैं। चूंकि क्लोजर में thresholdका संदर्भ होता है। अतः अधिकांशतः जब फ़िल्टर इसे कॉल करता है तब वह उस चर का उपयोग कर सकता है। फंक्शन filter पूर्ण प्रकार से भिन्न फ़ाइल में परिभाषित किया जा सकता है।

यहाँ उसी उदाहरण को जावालिपि में फिर से लिखा गया है। अतः क्लोजर के लिए समर्थन के साथ अन्य लोकप्रिय भाषा,

विक्रय की गई कम से कम 'दहलीज' प्रतियों वाली सभी पुस्तकों की सूची को वापस किया जाता है।

सबसे अधिक विक्रय होने वाली पुस्तकें (सीमा) कार्य करता है। {

 // Return a list of all books with at least 'threshold' copies sold.
function bestSellingBooks(threshold) {
  return bookList.filter(
      function (book) { return book.sales >= threshold; }
    );
}

lambdaके अतिरिक्त function संपर्क का प्रयोग यहा किया जाता है और वैश्विक filter फंक्शन के अतिरिक्त Array.filter विधि[8] का उपयोग किया जाता है। किन्तु संरचना और कोड का प्रभाव समान होता है। फंक्शन क्लोजर बना सकता है और इसे वापस कर सकता है। जैसा कि निम्नलिखित उदाहरण में है।

// फंक्शन वापस करता है जो एफ के व्युत्पन्न का अनुमान लगाता है।

// डीएक्स के अंतराल का उपयोग करता है। जो उचित रूप से छोटा होना चाहिए।

फंक्शन व्युत्पन्न (एफ, डीएक्स) {

 // Return a function that approximates the derivative of f
// using an interval of dx, which should be appropriately small.
function derivative(f, dx) {
  return function (x) {
    return (f(x + dx) - f(x)) / dx;
  };
}

चूंकि इस स्थितियों में क्लोजर होने से उस फंक्शन के निष्पादन की अवधि समाप्त हो जाती है। जो इसे बनाता है। चर f और dx फंक्शन derivative वापसी के पश्चात् रहते है। यदि निष्पादन ने अपनी सीमा को छोड़ दिया हो और वह अब दिखाई नहीं दे रहे हैं। क्लोजर के बिना भाषाओं में, स्वचालित स्थानीय चर का जीवनकाल समुदाय फ्रेम के निष्पादन के साथ मेल खाता है। जहां उस चर को घोषित किया जाता है। क्लोजर वाली भाषाओं में, चर तब तक उपस्तिथ रहना चाहिए। जब तक कि किसी भी उपस्तिथ क्लोजर में उनका संदर्भ होता है। यह सामान्यतः किसी प्रकार के कचरा संग्रह (कंप्यूटर विज्ञान) का उपयोग करके कार्यान्वित किया जाता है।

राज्य प्रतिनिधित्व

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

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

अन्य उपयोग

क्लोजर के अनेक उपयोग हैं:

  • चूंकि क्लोजर होने से मूल्यांकन में देरी होती है।अर्थात्, वह तब तक कुछ नहीं करते जब तक उन्हें बुलाया नहीं जाता है।उनका उपयोग नियंत्रण संरचनाओं को परिभाषित करने के लिए किया जा सकता है। उदाहरण के लिए, लघु वार्ता की सभी मानक नियंत्रण संरचनाएँ है। जिनमें शाखाएँ (यदि/तब/अन्य) और छोरों (जबकि और के लिए) सम्मिलित हैं। उन वस्तुओं का उपयोग करके परिभाषित की जाती हैं। जिनकी विधि क्लोजर स्वीकार करते हैं। उपयोक्ता अपनी स्वयं की नियंत्रण संरचनाओं को भी सरलता से परिभाषित कर सकते हैं।
  • उन भाषाओं में जो कार्य को प्रयुक्त करती हैं। वातावरण के समीप अनेक फंक्शन उत्पन्न किए जा सकते हैं, जिससे वह उस योजना में वातावरण को परिवर्तित करके व्यक्तिगत रूप से संवाद करने में सक्षम हो जाते हैं।
(define foo #f)
(define bar #f)

(let ((secret-message "none"))
  (set! foo (lambda (msg) (set! secret-message msg)))
  (set! bar (lambda () secret-message)))

(display (bar)) ; prints "none"
(newline)
(foo "meet me by the docks at midnight")
(display (bar)) ; prints "meet me by the docks at midnight"
  • नामांकन-उन्मुख प्रोग्रामिंग सिस्टम को प्रयुक्त करने के लिए क्लोजर का उपयोग किया जा सकता है।[9]

नोट: कुछ वक्ता किसी भी डेटा संरचना को कॉल करते हैं। जो विस्तार (प्रोग्रामिंग) शाब्दिक विस्तार वातावरण को क्लोजर से बांधता है। किन्तु यह शब्द सामान्यतः विशेष रूप से फंक्शन को संदर्भित करता है।

कार्यान्वयन और सिद्धांत

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

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

यह बताता है कि सामान्यतः मूल रूप से क्लोजर का समर्थन करने वाली भाषाएं कचरा संग्रह (कंप्यूटर विज्ञान) का उपयोग क्यों करती हैं। चूँकि विकल्प गैर-स्थानीय चर के मैनुअल स्मृति प्रबंधन हैं। (स्पष्ट रूप से संचय पर आवंटन और किए जाने पर मुक्त) या यदि समुदाय आवंटन का उपयोग करते हैं। तब भाषा के लिए यह स्वीकार करने के लिए कि कुछ उपयोग के स्थितियों अपरिभाषित व्यवहार की ओर ले जाते है। लटकने वाले सूचक के कारण सी ++ 11 में लैम्ब्डा अभिव्यक्ति के रूप में मुक्त स्वचालित चर[10] या जीएनयू सी में स्थिर फंक्शन के रूप में मुक्त स्वचालित चर होता है।[11] फनार्ग समस्या (या कार्यात्मक तर्क समस्या) सी या सी ++ जैसी समुदाय-आधारित प्रोग्रामिंग भाषा में प्रथम श्रेणी की वस्तुओं के रूप में फंक्शन को प्रयुक्त करने में कठिनाई का वर्णन करती है। इसी प्रकार डी (प्रोग्रामिंग भाषा) संस्करण 1 में, यह माना जाता है कि प्रोग्रामर जानता है कि प्रतिनिधिमंडल (प्रोग्रामिंग) और स्वचालित स्थानीय चर के साथ क्या करना है। चूंकि इसकी परिभाषा के क्षेत्र से लौटने के पश्चात् उनके संदर्भ अमान्य हो जाते है। (स्वचालित स्थानीय चर ढेर पर हैं।) - यह अभी भी अनेक उपयोगी कार्यात्मक पैटर्न की अनुमति देता है। किन्तु जटिल स्थितियों के लिए चर के स्पष्ट संचय आवंटन की आवश्यकता होती है। डी संस्करण 2 ने यह पता लगाने के द्वारा हल किया कि कौन से चर को ढेर पर संग्रहीत किया जाना है और स्वचालित आवंटन करता है। चूंकि डी कचरा संग्रह का उपयोग करता है। अतः दोनों संस्करणों में, चर के उपयोग को ट्रैक करने की कोई आवश्यकता नहीं है, चूंकि वह समीप होते हैं।

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

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

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

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

क्लोजर फंक्शन वस्तु से निकटता से संबंधित होता हैं। अतः पूर्व से दूसरे में परिवर्तन को निष्क्रियता या लैम्ब्डा उठाना के रूप में जाना जाता है। क्लोजर रूपांतरण भी देख सकते है।

शब्दार्थ में अंतर

शाब्दिक वातावरण

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

// Javascript
var f, g;
function foo() {
  var x;
  f = function() { return ++x; };
  g = function() { return --x; };
  x = 1;
  alert('inside foo, call to f(): ' + f());
}
foo();  // 2
alert('call to g(): ' + g());  // 1 (--x)
alert('call to g(): ' + g());  // 0 (--x)
alert('call to f(): ' + f());  // 1 (++x)
alert('call to f(): ' + f());  // 2 (++x)

फंक्शन foo और चरों f और g द्वारा संदर्भित क्लोजर सभी स्थानीय चर x द्वारा दर्शाए गए समान सापेक्ष स्मृति स्थान का उपयोग करते हैं।

कुछ उदाहरणों में उपरोक्त व्यवहार अवांछनीय हो सकता है और भिन्न शाब्दिक समापन को बांधना आवश्यक है। पुनः ईसीएमए लिपि में Function.bind()का उपयोग करके किया जाता है।

उदाहरण 1: असीमित चर का संदर्भ

[13]

 var module = {
  x: 42,
  getX: function() {return this.x; }
}
var unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// emits undefined as 'x' is not specified in global scope.

var boundGetX = unboundGetX.bind(module); // specify object module as the closure
console.log(boundGetX()); // emits 42

उदाहरण 2: बाध्य चर के लिए आकस्मिक संदर्भ

इस उदाहरण के लिए अपेक्षित व्यवहार यह होता है कि क्लिक किए जाने पर प्रत्येक लिंक को अपनी आईडी छोड़नी होती है। किन्तु चर 'ई' उपरोक्त क्षेत्र से जुड़ा हुआ है और क्लिक पर मुक्त मूल्यांकन किया गया है। वास्तव में यह होता है कि प्रत्येक क्लिक आयोजन के अंतिम तत्व की आईडी को लूप के अंत में बंधे 'तत्व' में उत्सर्जित करता है।[14]

var elements= document.getElementsByTagName('a');

//Incorrect: e is bound to the function containing the 'for' loop, not the closure of "handle"

for (var e of elements){ e.onclick=function handle(){ alert(e.id);} }

यहाँ पुनः परिवर्तनशील e का उपयोग करके ब्लॉक के क्षेत्र से बंधे होने पर handle.bind(this) या letसंपर्क की आवश्यकता होती है।

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

कुछ भाषाएँ आपको चर या उसके स्थान के मान को अधिकृत करने के मध्य चयन करने में सक्षम बनाती हैं। उदाहरण के लिए, सी ++ 11 में, अधिकृत किए गए चर [&] या [=] तब घोषित किए जाते हैं। जिसका अर्थ है संदर्भ द्वारा या साथ में कब्जा कर लिया गया है।

फिर भी और उपसमूह, मुक्त मूल्यांकन कार्यात्मक भाषाएं जैसे हास्केल (प्रोग्रामिंग भाषा), मूल्यों के अतिरिक्त भविष्य की संगणनाओं के परिणामों के लिए चर को बांधती हैं। हास्केल में इस उदाहरण पर विचार कर सकते है।

-- Haskell
foo :: Fractional a => a -> a -> (a -> a)
foo x y = (\z -> z + r)
          where r = x / y

f :: Fractional a => a -> a
f = foo 1 0


main = print (f 123)

फंक्शन के अंदर परिभाषित क्लोजर द्वारा अधिकृत किया गया r का बंधन गणना (x / y) के लिए है। जो इस स्थितियों में शून्य से विभाजन में परिणत होता है। चूंकि यह अभिकलन है जो अधिकृत किया गया है। न कि मान, त्रुटि केवल तभी प्रकट होती है। जब क्लोजर का आह्वान किया जाता है,और वास्तव में अधिकृत किए गए आबद्धिंग का उपयोग करने का प्रयास करता है।

क्लोजर छोड़ना

सामान्यतः अधिक अंतर स्वयं को अन्य व्याख्यात्मक रूप से निर्मित निर्माणों के व्यवहार में प्रकट करते हैं। जैसे कि return, break और continue कथन इस प्रकार के निर्माण, सामान्य रूप से, संलग्न नियंत्रण विवरण (के स्थितियों में) द्वारा स्थापित पलायन निरंतरता को प्रयुक्त करने के संदर्भ में माना जा सकता है। break और continue इस प्रकार की व्याख्या के लिए पुनरावर्ती फंक्शन कॉल के संदर्भ में लूपिंग निर्माणों पर विचार करने की आवश्यकता होती है)। कुछ भाषाओं में, जैसे ईसीएमए लिपि, returnकथन के संबंध में व्याख्यात्मक रूप से आंतरिक रूप से क्लोजर द्वारा स्थापित निरंतरता को संदर्भित करता है। इस प्रकार, ए returnक्लोजर के अंदर उस कोड को नियंत्रण स्थानांतरित करता है जिसने इसे बुलाया था। चूँकि, लघु वार्ता में, सतही रूप से समान ऑपरेटर ^ किसी भी हस्तक्षेप करने वाले स्थिर क्लोजर के एस्केप निरंतरता को अनदेखा करते हुए, विधि आमंत्रण के लिए स्थापित एस्केप निरंतरता को आमंत्रित करता है। क्लोजर के कोड के अंत तक पहुंचकर किसी विशेष क्लोजर की एस्केप निरंतरता को केवल लघु वार्ता में प्रयुक्त किया जा सकता है। ईसीएमए लिपि और लघु वार्ता में निम्नलिखित उदाहरण अंतर को उजागर करते हैं।

"Smalltalk"
foo
  | xs |
  xs := #(1 2 3 4).
  xs do: [:x | ^x].
  ^0
bar
  Transcript show: (self foo printString) "prints 1"
// ECMAScript
function foo() {
  var xs = [1, 2, 3, 4];
  xs.forEach(function (x) { return x; });
  return 0;
}
alert(foo()); // prints 0

उपरोक्त कोड के टुकड़े भिन्न प्रकार से व्यवहार करते है। चूंकि लघु वार्ता ^ ऑपरेटर और जावालिपि return ऑपरेटर अनुरूप नहीं हैं। ईसीएमए लिपि उदाहरण में, return x का नया पुनरावृति प्रारंभ करने के लिए आंतरिक समापन को छोड़ देता है जिससे कि लघु वार्ता उदाहरण में, ^x लूप को निरस्त कर देता है और विधि foo से वापस आ जाता है।

अधिकांशतः सामान्य लिस्प निर्माण प्रदान करता है। जो उपरोक्त फंक्शन में से किसी को व्यक्त कर सकता है। लिस्प (return-from foo x) लघु वार्ता ^x के रूप में व्यवहार करता है। जिससे कि लिस्प (return-from nil x) जावालिपि return x के रूप में व्यवहार करता है। अतः, लघु वार्ता अधिकृत किए गए एस्केप निरंतरता को उस सीमा तक जीवित रहने के लिए संभव बनाता है। जिसमें इसे सफलतापूर्वक प्रयुक्त किया जा सकता है। विचार करना,

"Smalltalk"
foo
    ^[ :x | ^x ]
bar
    | f |
    f := self foo.
    f value: 123 "error!"

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

कुछ भाषाएँ, जैसे रूबी (प्रोग्रामिंग भाषा), प्रोग्रामर को return कब्जा करने की विधि चुनने में सक्षम बनाती हैं। रूबी में उदाहरण,

# Ruby

# Closure using a Proc
def foo
  f = Proc.new { return "return from foo from inside proc" }
  f.call # control leaves foo here
  return "return from foo"
end

# Closure using a lambda
def bar
  f = lambda { return "return from lambda" }
  f.call # control does not leave bar here
  return "return from bar"
end

puts foo # prints "return from foo from inside proc"
puts bar # prints "return from bar"

दोनों Proc.new और lambda इस उदाहरण में क्लोजर बनाने के विधि हैं। किन्तु इस प्रकार से बनाए गए क्लोजर return कथन के शब्दार्थ इसके संबंध में भिन्न हैं।

योजना (प्रोग्रामिंग भाषा) में, return नियंत्रण की परिभाषा और कार्यक्षेत्र स्पष्ट है। ( उदाहरण के लिए केवल अनैतिक रूप से 'वापसी' नाम दिया गया है।) निम्नलिखित रूबी प्रतिरूप का सीधा अनुवाद है।

योजना

(कॉल/सीसी कॉल-साथ-वर्तमान-निरंतरता को परिभाषित कर सकते है।)

(परिभाषित करें (फू)

 ; Scheme
(define call/cc call-with-current-continuation)

(define (foo)
  (call/cc
   (lambda (return)
     (define (f) (return "return from foo from inside proc"))
     (f) ; control leaves foo here
     (return "return from foo"))))

(define (bar)
  (call/cc
   (lambda (return)
     (define (f) (call/cc (lambda (return) (return "return from lambda"))))
     (f) ; control does not leave bar here
     (return "return from bar"))))

(display (foo)) ; prints "return from foo from inside proc"
(newline)
(display (bar)) ; prints "return from bar"

क्लोजर-जैसी संरचनाएं

सामान्यतः कुछ भाषाओं में विशेषताएं होती हैं। जो क्लोजर के व्यवहार का अनुकरण करती हैं। जावा, सी++, उद्देश्य सी, सी#, वीबी.नेट और डी जैसी भाषाओं में, ये विशेषताएँ भाषा के वस्तु-उन्मुख प्रतिमान का परिणाम हैं।

कॉलबैक (सी)

सामान्यतः कुछ पुस्तकालय कॉलबैक सी (प्रोग्रामिंग भाषा) समर्थन करते हैं। पुस्तकालय के साथ कॉलबैक (कंप्यूटर विज्ञान) पंजीकृत करते समय इसे कभी-कभी दो मान प्रदान करके कार्यान्वित किया जाता है। उपयोगकर्ता की पसंद के अनैतिक डेटा के लिए फ़ंक्शन सूचक और और void*सूचक होता है। जब पुस्तकालय कॉलबैक फंक्शन निष्पादित करता है तब यह डेटा सूचक के साथ गुजरता है। यह कॉलबैक को राज्य को बनाये रखने और पुस्तकालय के साथ पंजीकृत होने के समय कैप्चर की गई जानकारी को संदर्भित करने में सक्षम बनाता है। मुहावरा कार्यक्षमता में क्लोजर होने के समान है। किन्तु वाक्य - विन्यास में नहीं void* सूचक टाइप सुरक्षित नहीं है, चूँकि यह सी मुहावरा सी #, हास्केल या एमएल में टाइप-सुरक्षित क्लोजर से भिन्न है।

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

स्थिर फंक्शन और फंक्शन सूचक (सी)

जीसीसी विस्तार के साथ, स्थिर फंक्शन का उपयोग किया जा सकता है और फंक्शन सूचक क्लोजर का अनुकरण कर सकता है। अतः फंक्शन युक्त क्षेत्र से बाहर नही होता है। निम्न उदाहरण अमान्य है। चूंकि adder शीर्ष-स्तरीय परिभाषा है। (संकलक संस्करण के आधार पर, यह अनुकूलन के बिना संकलित होने पर सही परिणाम उत्पन्न कर सकता है। अर्थात -O0):

#include <stdio.h>

typedef int (*fn_int_to_int)(int); // type of function int->int

fn_int_to_int adder(int number) {
  int add (int value) { return value + number; }
  return &add; // & operator is optional here because the name of a function in C is a pointer pointing on itself
}

int main(void) {
  fn_int_to_int add10 = adder(10);
  printf("%d\n", add10(1));
  return 0;

किन्तु adder (और, वैकल्पिक रूप से, typedef) में main इसे वैध बनाता है।

 #include <stdio.h>
int main(void) {
  typedef int (*fn_int_to_int)(int); // type of function int->int
  
  fn_int_to_int adder(int number) {
    int add (int value) { return value + number; }
    return add;
  }
  
  fn_int_to_int add10 = adder(10);
  printf("%d\n", add10(1));
  return 0;

यदि इसे क्रियान्वित किया जाता है तब यह आशा के अनुसार 11 मुद्रण करता है।

स्थानीय वर्ग और लैम्ब्डा फंक्शन (जावा)

जावा (प्रोग्रामिंग भाषा) कक्षाओं को (वस्तु-उन्मुख प्रोग्रामिंग) को विधि (वस्तु-उन्मुख प्रोग्रामिंग) के अंदर परिभाषित करने में सक्षम बनाता है। इन्हें स्थानीय वर्ग कहा जाता है। जब ऐसी कक्षाओं का नाम नहीं दिया जाता है। तब उन्हें अनाम वर्ग (या अनाम आंतरिक वर्ग) के रूप में जाना जाता है। स्थानीय वर्ग (या तब नामित या अनाम) शाब्दिक रूप से संलग्न कक्षाओं में नामों का उल्लेख कर सकता है। या शाब्दिक रूप से संलग्न विधि में केवल-पढ़ने के लिए चर ( final के रूप में चिह्नित) का उल्लेख कर सकता है।

 class CalculationWindow extends JFrame {
    private volatile int result;
    // ...
    public void calculateInSeparateThread(final URI uri) {
        // The expression "new Runnable() { ... }" is an anonymous class implementing the 'Runnable' interface.
        new Thread(
            new Runnable() {
                void run() {
                    // It can read final local variables:
                    calculate(uri);
                    // It can access private fields of the enclosing class:
                    result = result + 10;
                }
            }
        ).start();
    }
}

final चरों को अधिकृत करने से आप चरों के मान अनुसार अधिकृत कर सकते है। यदि आप जिस चर को अधिकृत करना चाहते हैं वह गैर- final है आप हमेशा कक्षा के ठीक पूर्व अस्थायी अंतिम चर में कॉपी कर सकते हैं।

संदर्भ द्वारा चरो को अधिकृत करना परिवर्तनशील कंटेनर का संदर्भ के final संदर्भ का उपयोग करके अनुकरण किया जा सकता है। उदाहरण के लिए, एकल-तत्व सरणी स्थानीय वर्ग स्वयं कंटेनर संदर्भ के मूल्य को परिवर्तित करने में सक्षम नहीं होगा, किन्तु यह कंटेनर की सामग्री को परिवर्तितने में सक्षम होता है।

जावा 8 के लैम्ब्डा भावों के आगमन के साथ,[15] क्लोजर के कारण उपरोक्त कोड को निष्पादित कर सकता है।

class CalculationWindow extends JFrame {
    private volatile int result;
    // ...
    public void calculateInSeparateThread(final URI uri) {
        // The code () -> { /* code */ } is a closure.
        new Thread(() -> {
            calculate(uri);
            result = result + 10;
        }).start();
    }

स्थानीय वर्ग प्रकार के आंतरिक वर्ग हैं जो विधि के शरीर के अंदर घोषित किए जाते हैं। जावा आंतरिक कक्षाओं का भी समर्थन करता है जिन्हें संलग्न वर्ग के गैर-स्थैतिक सदस्यों के रूप में घोषित किया जाता है।[16] उन्हें सामान्यतः आंतरिक कक्षाओं के रूप में संदर्भित किया जाता है।[17] इन्हें संलग्न वर्ग के शरीर में परिभाषित किया गया है और संलग्न वर्ग के आवृत्ति चरों तक पूर्ण पहुंच है। इन इंस्टेंस चरों के लिए उनके बंधन के कारण, विशेष वाक्य - विन्यास का उपयोग करके संलग्न वर्ग के उदाहरण के लिए स्पष्ट बंधन के साथ आंतरिक वर्ग को केवल तत्काल किया जा सकता है।[18]

public class EnclosingClass {
    /* Define the inner class */
    public class InnerClass {
        public int incrementAndReturnCounter() {
            return counter++;
        }
    }

    private int counter;
    {
        counter = 0;
    }

    public int getCounter() {
        return counter;
    }

    public static void main(String[] args) {
        EnclosingClass enclosingClassInstance = new EnclosingClass();
        /* Instantiate the inner class, with binding to the instance */
        EnclosingClass.InnerClass innerClassInstance =
            enclosingClassInstance.new InnerClass();

        for (int i = enclosingClassInstance.getCounter();
             (i = innerClassInstance.incrementAndReturnCounter()) < 10;
             /* increment step omitted */) {
            System.out.println(i);
        }
    }
}

निष्पादन पर, यह 0 से 9 तक के पूर्णांकों को मुद्रण करना करता है। इस प्रकार के वर्ग को स्थिर वर्ग के साथ भ्रमित न करने के लिए सावधान रहते है, जो उसी प्रकार से घोषित किया जाता है जैसे स्थैतिक संशोधक के उपयोग के साथ किया जाता है। उनका वांछित प्रभाव नहीं है, बल्कि केवल वह वर्ग हैं जिनके समीप संलग्न वर्ग में परिभाषित कोई विशेष बंधन नहीं है।

जावा संस्करण इतिहास जावा_8 के रूप में, जावा प्रथम श्रेणी की वस्तुओं के रूप में फंक्शन का समर्थन करता है। इस रूप के लैम्ब्डा भावों को Function<T,U> प्रकार का माना जाता है। जहां टी डोमेन है और यू छवि प्रकार है। व्यंजक को इसके .apply(T t) विधि से कॉल किया जा सकता है। किन्तु मानक विधि कॉल के साथ नहीं किया जाता है।

public static void main(String[] args) {
    Function<String, Integer> length = s -> s.length();

    System.out.println( length.apply("Hello, world!") ); // Will print 13.

ब्लॉक (सी, सी ++, वस्तुिव-सी 2.0)

ऐप्पल ने सी, सी ++, वस्तुिव-सी 2.0 और मैक ओएस एक्स 10.6 "स्नो लेपर्ड" और आईओएस 4.0 में गैर-मानक विस्तार के रूप में ब्लॉक, क्लोजर के रूप प्रस्तुत किया जाता है। ऐप्पल ने जीसीसी और क्लैंग कंपाइलर्स के लिए अपना कार्यान्वयन उपलब्ध कराया है।

शाब्दिक ब्लॉक और ब्लॉक करने के लिए सूचक को चिह्नित किया गया है। ^ ब्लॉक बनाया जाता है। तब सामान्य स्थानीय चर मूल्य द्वारा कब्जा कर लिया जाता है और केवल पढ़ने के लिए ब्लॉक के अंदर होता है। संदर्भ द्वारा अधिकृत किए जाने वाले चरों को __block चिह्नित किया गया है। जिन ब्लॉकों को उनके द्वारा बनाए गए क्षेत्र से बाहर बने रहने की आवश्यकता है। उन्हें कॉपी करने की आवश्यकता हो सकती है।[19][20]

typedef int (^IntBlock)();

IntBlock downCounter(int start) { __block int i = start; return [[ ^int() { return i--; } copy] autorelease]; }

IntBlock f = downCounter(5); NSLog(@"%d", f()); NSLog(@"%d", f()); NSLog(@"%d", f());

प्रतिनिधि (सी #, वीबी.नेट, डी)

सी शार्प (प्रोग्रामिंग भाषा) | सी # अनाम विधि और लैम्ब्डा अभिव्यक्ति क्लोजर का समर्थन करते हैं।

var data = new[] {1, 2, 3, 4};
var multiplier = 2; 

मूल दृश्य .नेट, जिसमें सी# के समान अनेक भाषा सुविधाएँ हैं, क्लोजर के साथ लैम्ब्डा अभिव्यक्ति का भी समर्थन करता है।

Dim data = {1, 2, 3, 4}

Dim multiplier = 2
Dim result = data.Select(Function(x) x * multiplier)

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

auto test1() {
    int a = 7;
    return delegate() { return a + 3; }; // anonymous delegate construction
}

auto test2() {
    int a = 20;
    int foo() { return a + 5; } // inner function
    return &foo;  // other way to construct delegate
}

void bar() {
    auto dg = test1();
    dg();    // =10   // ok, test1.a is in a closure and still exists

    dg = test2();
    dg();    // =25   // ok, test2.a is in a closure and still exists
}

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

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

फंक्शन वस्तु्स (सी ++)

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

शून्य फू (स्ट्रिंग मायनाम) {

void foo(string myname) {
    int y;
    vector<string> n;
    // ...
    auto i = std::find_if(n.begin(), n.end(),
               // this is the lambda expression:
               [&](const string& s) { return s != myname && s.size() > y; }
             );
    // 'i' is now either 'n.end()' or points to the first string in 'n'
    // which is not equal to 'myname' and whose length is greater than 'y'

}

इनलाइन एजेंट (एफिल)

एफिल (प्रोग्रामिंग भाषा) में क्लोजर को परिभाषित करने वाले इनलाइन एजेंट सम्मिलित हैं। इनलाइन एजेंट रूटीन का प्रतिनिधित्व करने वाली वस्तु है। जिसे रूटीन इन-लाइन का कोड देकर परिभाषित किया जाता है। उदाहरण के लिए, में

ok_button.click_event.subscribe (

agent (x, y: INTEGER) do

map.country_at_coordinates (x, y).display

end

)

सदस्यता लेने का तर्क subscribeएजेंट है। जो दो तर्कों के साथ प्रक्रिया का प्रतिनिधित्व करता है। प्रक्रिया देश को संबंधित निर्देशांक पर ढूंढती है और इसे click_event के लिए प्रदर्शित करती है। पूरे एजेंट को ईवेंट प्रकार की सदस्यता दी गई है।

निश्चित बटन, जिससे कि जब भी उस बटन पर घटना प्रकार का उदाहरण होता है। चूंकि उपयोगकर्ता ने बटन पर क्लिक किया है। x और yप्रक्रिया को माउस निर्देशांक के साथ तर्क के रूप में पारित किया जाता है।

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

सी ++ बिल्डर क्लोजर आरक्षित शब्द

एम्बरकाडेरो सी++ निर्माता फंक्शन सूचक के समान वाक्य - विन्यास वाली विधि को सूचक प्रदान करने के लिए आरक्षित शब्द _ क्लोजर प्रदान करता है।[21]

मानक सी में आप एलिख सकते हैं टाइपपीफ निम्नलिखित वाक्य - विन्यास का उपयोग करके फंक्शन प्रकार के सूचक के लिए कार्य करता है।

typedef void (*TMyFunctionPointer)( void );

इसी प्रकार से आप घोषित कर सकते हैं ए टाइपपीफ निम्नलिखित वाक्य - विन्यास का उपयोग करने वाली विधि के लिए सूचक के लिए:<वाक्य - विन्यास प्रमुखता लंग= सी++ >

typedef void (__closure *TMyMethodPointer)();

यह भी देखें

टिप्पणियाँ

  1. These names most frequently refer to values, mutable variables, or functions, but can also be other entities such as constants, types, classes, or labels.


संदर्भ

  1. Sussman and Steele. "Scheme: An interpreter for extended lambda calculus". "... a data structure containing a lambda expression, and an environment to be used when that lambda expression is applied to arguments." (Wikisource)
  2. David A. Turner (2012). "Some History of Functional Programming Languages". Trends in Functional Programming '12. Section 2, note 8 contains the claim about M-expressions.
  3. P. J. Landin (1964), The mechanical evaluation of expressions
  4. Joel Moses (June 1970), The Function of FUNCTION in LISP, or Why the FUNARG Problem Should Be Called the Environment Problem, hdl:1721.1/5854, AI Memo 199, A useful metaphor for the difference between FUNCTION and QUOTE in LISP is to think of QUOTE as a porous or an open covering of the function since free variables escape to the current environment. FUNCTION acts as a closed or nonporous covering (hence the term "closure" used by Landin). Thus we talk of "open" Lambda expressions (functions in LISP are usually Lambda expressions) and "closed" Lambda expressions. [...] My interest in the environment problem began while Landin, who had a deep understanding of the problem, visited MIT during 1966–67. I then realized the correspondence between the FUNARG lists which are the results of the evaluation of "closed" Lambda expressions in LISP and ISWIM's Lambda Closures.
  5. Åke Wikström (1987). Functional Programming using Standard ML. ISBN 0-13-331968-7. The reason it is called a "closure" is that an expression containing free variables is called an "open" expression, and by associating to it the bindings of its free variables, you close it.
  6. Gerald Jay Sussman and Guy L. Steele, Jr. (December 1975), Scheme: An Interpreter for the Extended Lambda Calculus, AI Memo 349
  7. Abelson, Harold; Sussman, Gerald Jay; Sussman, Julie (1996). Structure and Interpretation of Computer Programs. Cambridge, MA: MIT Press. p. 98–99. ISBN 0262510871.
  8. "array.filter". Mozilla Developer Center. 10 January 2010. Retrieved 2010-02-09.
  9. "Re: FP, OO and relations. Does anyone trump the others?". 29 December 1999. Archived from the original on 26 December 2008. Retrieved 2008-12-23.
  10. Lambda Expressions and Closures C++ Standards Committee. 29 February 2008.
  11. GCC Manual, 6.4 Nested Functions, "If you try to call the nested function through its address after the containing function exits, all hell breaks loose. If you try to call it after a containing scope level exits, and if it refers to some of the variables that are no longer in scope, you may be lucky, but it's not wise to take the risk. If, however, the nested function does not refer to anything that has gone out of scope, you should be safe."
  12. Foundations of Actor Semantics Will Clinger. MIT Mathematics Doctoral Dissertation. June 1981.
  13. "Function.prototype.bind()". MDN Web Docs. Retrieved 20 November 2018.
  14. "Closures". MDN Web Docs. Retrieved 20 November 2018.
  15. "Lambda Expressions (The Java Tutorials)".
  16. "Nested, Inner, Member, and Top-Level Classes".
  17. "Inner Class Example (The Java Tutorials > Learning the Java Language > Classes and Objects)".
  18. "Nested Classes (The Java Tutorials > Learning the Java Language > Classes and Objects)".
  19. Apple Inc. "Blocks Programming Topics". Retrieved 2011-03-08.
  20. Joachim Bengtsson (7 July 2010). "Programming with C Blocks on Apple Devices". Archived from the original on 25 October 2010. Retrieved 2010-09-18.
  21. Full documentation can be found at http://docwiki.embarcadero.com/RADStudio/Rio/en/Closure


बाहरी संबंध