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

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

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

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

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

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

डीईएफ़ एच (एक्स): रिटर्न लैम्ब्डा वाई: एक्स + वाई # एक क्लोजर लौटाएं।

ए = एफ (1) बी = एच (1)
 * 1) वेरिएबल्स को विशिष्ट क्लोजर असाइन करना।

ए (5) == 6 पर जोर दें जोर बी (5) == 6
 * 1) वेरिएबल्स में स्टोर किए गए क्लोजर का उपयोग करना।

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

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

नेस्टेड फ़ंक्शन परिभाषाएं स्वयं क्लोजर नहीं हैं: उनके पास एक फ्री वेरिएबल है जो अभी तक बाध्य नहीं है। केवल एक बार एनक्लोजिंग फ़ंक्शन का मूल्यांकन पैरामीटर के मान के साथ किया जाता है, नेस्टेड फ़ंक्शन बाउंड का फ्री वेरिएबल होता है, जो क्लोजर बनाता है, जिसे बाद में एनक्लोजिंग फ़ंक्शन से लौटाया जाता है।

अंत में, गैर-स्थानीय चर के दायरे से बाहर होने पर एक क्लोजर केवल मुक्त चर वाले फ़ंक्शन से अलग होता है, अन्यथा परिभाषित वातावरण और निष्पादन वातावरण मेल खाते हैं और इन्हें अलग करने के लिए कुछ भी नहीं है (स्थैतिक और गतिशील बाध्यकारी को अलग नहीं किया जा सकता है क्योंकि नाम समान मानों को हल करते हैं)। उदाहरण के लिए, नीचे दिए गए प्रोग्राम में, फ्री वेरिएबल के साथ कार्य करता है  (गैर-स्थानीय चर के लिए बाध्य   वैश्विक दायरे के साथ) उसी वातावरण में क्रियान्वित किए जाते हैं जहाँ   परिभाषित किया गया है, इसलिए यह सारहीन है कि क्या ये वास्तव में बंद हैं: <वाक्यविन्यास लैंग = अजगर> एक्स = 1 अंक = [1, 2, 3]

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

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

यह चर छायांकन (जो गैर-स्थानीय चर के दायरे को कम करता है) द्वारा भी प्राप्त किया जा सकता है, हालांकि व्यवहार में यह कम आम है, क्योंकि यह कम उपयोगी है और शैडोइंग को हतोत्साहित किया जाता है। इस उदाहरण में  बंद होने के रूप में देखा जा सकता है क्योंकि   के शरीर में   के लिए बाध्य है   वैश्विक नामस्थान में, नहीं   स्थानीय के लिए  : <वाक्यविन्यास लैंग = अजगर> एक्स = 0

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

डेफ जी (जेड): x = 1 # स्थानीय x छाया वैश्विक x   रिटर्न एफ (जेड)

g(1) # 1 का मूल्यांकन करता है, 2 का नहीं 

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

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

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

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

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

यहाँ उसी उदाहरण को जावास्क्रिप्ट में फिर से लिखा गया है, क्लोजर के लिए समर्थन के साथ एक अन्य लोकप्रिय भाषा: <वाक्यविन्यास लैंग = जावास्क्रिप्ट> // बेची गई कम से कम 'दहलीज' प्रतियों वाली सभी पुस्तकों की सूची लौटाएं। सबसे अधिक बिकने वाली पुस्तकें (दहलीज) कार्य करें { रिटर्न बुकलिस्ट.फ़िल्टर (     समारोह (पुस्तक) {पुस्तक वापस करें। बिक्री> = सीमा; }    ); }   की जगह यहाँ e> कीवर्ड का प्रयोग किया गया है , और एक   तरीका एक वैश्विक के बजाय   कार्य करता है, लेकिन अन्यथा संरचना और कोड का प्रभाव समान होता है।

एक फ़ंक्शन एक क्लोजर बना सकता है और इसे वापस कर सकता है, जैसा कि निम्नलिखित उदाहरण में है:

<वाक्यविन्यास लैंग = जावास्क्रिप्ट> // एक फ़ंक्शन लौटाएं जो f के व्युत्पन्न का अनुमान लगाता है // डीएक्स के अंतराल का उपयोग करना, जो उचित रूप से छोटा होना चाहिए। फ़ंक्शन डेरिवेटिव (एफ, डीएक्स) { वापसी समारोह (एक्स) { रिटर्न (एफ(एक्स + डीएक्स) - एफ(एक्स)) / डीएक्स; }; } 

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

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

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

अन्य उपयोग
क्लोजर के कई उपयोग हैं:
 * क्योंकि बंद होने से मूल्यांकन में देरी होती है—अर्थात्, वे तब तक कुछ नहीं करते जब तक उन्हें बुलाया नहीं जाता—उनका उपयोग नियंत्रण संरचनाओं को परिभाषित करने के लिए किया जा सकता है। उदाहरण के लिए, स्मॉलटाक की सभी मानक नियंत्रण संरचनाएँ, जिनमें शाखाएँ (यदि/तब/अन्य) और लूप्स (जबकि और के लिए) शामिल हैं, उन वस्तुओं का उपयोग करके परिभाषित की जाती हैं जिनके तरीके क्लोजर स्वीकार करते हैं। उपयोक्ता अपनी स्वयं की नियंत्रण संरचनाओं को भी आसानी से परिभाषित कर सकते हैं।
 * उन भाषाओं में जो असाइनमेंट को लागू करती हैं, एक ही वातावरण के करीब कई फ़ंक्शन उत्पन्न किए जा सकते हैं, जिससे वे उस वातावरण को बदलकर निजी तौर पर संवाद करने में सक्षम हो जाते हैं। योजना में:

<वाक्यविन्यास लैंग = योजना> (फू #f परिभाषित करें) (बार #f परिभाषित करें)

(चलो ((गुप्त-संदेश कोई नहीं)) (सेट! फू (लैम्ब्डा (संदेश) (सेट! गुप्त-संदेश संदेश))) (सेट! बार (लैम्ब्डा गुप्त-संदेश)))

(प्रदर्शन (बार)); प्रिंट कोई नहीं (नई पंक्ति) (आधी रात को मुझे गोदी से मिलो) (प्रदर्शन (बार)); प्रिंट मुझसे आधी रात को डॉक पर मिलते हैं 

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

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

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

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

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

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

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

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

<वाक्यविन्यास लैंग = एकमा स्क्रिप्ट> // जावास्क्रिप्ट वार एफ, जी; समारोह फू { वार एक्स; च = समारोह {वापसी ++x; }; जी = समारोह {वापसी --x; }; एक्स = 1; चेतावनी ('फू के अंदर, एफ को कॉल करें):' + एफ ); } फू ; // 2 चेतावनी ('जी को कॉल करें):' + जी ); // 1 (--x) चेतावनी ('जी को कॉल करें):' + जी ); // 0 (--x) चेतावनी ('कॉल टू एफ :' + एफ ); // 1 (++x) चेतावनी ('कॉल टू एफ :' + एफ ); // 2 (++x) 

समारोह  और वेरिएबल्स द्वारा संदर्भित क्लोजर   और   सभी स्थानीय चर द्वारा दर्शाए गए समान सापेक्ष स्मृति स्थान का उपयोग करते हैं.

कुछ उदाहरणों में उपरोक्त व्यवहार अवांछनीय हो सकता है, और एक अलग शाब्दिक समापन को बांधना आवश्यक है। फिर से ईसीएमएस्क्रिप्ट में, इसका उपयोग करके किया जाएगा.

उदाहरण 1: एक अनबाउंड वेरिएबल
का संदर्भ <वाक्यविन्यास लैंग = एक्मास्क्रिप्ट> वार मॉड्यूल = { एक्स: 42, getX: फ़ंक्शन {इसे वापस करें। x; } } var अनबाउंडगेटएक्स = मॉड्यूल.गेटएक्स; कंसोल.लॉग (अनबाउंडगेटएक्स ); // फ़ंक्शन को वैश्विक दायरे में लागू किया जाता है // अपरिभाषित उत्सर्जित करता है क्योंकि 'x' वैश्विक दायरे में निर्दिष्ट नहीं है।

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

उदाहरण 2: एक बाध्य चर के लिए आकस्मिक संदर्भ
इस उदाहरण के लिए अपेक्षित व्यवहार यह होगा कि क्लिक किए जाने पर प्रत्येक लिंक को अपनी आईडी छोड़नी चाहिए; लेकिन क्योंकि वेरिएबल 'ई' उपरोक्त दायरे से जुड़ा हुआ है, और क्लिक पर आलसी मूल्यांकन किया गया है, वास्तव में क्या होता है कि प्रत्येक क्लिक ईवेंट अंतिम तत्व की आईडी को लूप के अंत में बंधे 'तत्व' में उत्सर्जित करता है। <वाक्यविन्यास लैंग = एक्मास्क्रिप्ट> var एलिमेंट्स = document.getElementsByTagName ('ए'); // गलत: ई 'फॉर' लूप वाले फ़ंक्शन के लिए बाध्य है, न कि हैंडल को बंद करने के लिए के लिए (तत्वों का संस्करण) {e.onclick = फ़ंक्शन हैंडल {अलर्ट (e.id);}}  यहाँ फिर से परिवर्तनशील  का उपयोग करके ब्लॉक के दायरे से बंधे होने की आवश्यकता होगी   या   कीवर्ड।

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

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

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

<वाक्यविन्यास लैंग = हैकेल> -- हास्केल foo :: भिन्नात्मक a => a -> a -> (a -> a) फू x y = (\z -> z + r)         जहां आर = एक्स / वाई

f :: भिन्नात्मक a => a -> a एफ = फू 1 0

मुख्य = प्रिंट (एफ 123) 

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

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

<वाक्यविन्यास लैंग = स्मॉलटॉक> गपशप फू | एक्सएस | xs := #(1 2 3 4). xs करते हैं: [:x | ^ एक्स]। ^ 0 छड़ ट्रांसक्रिप्ट शो: (सेल्फ फू प्रिंटस्ट्रिंग) प्रिंट 1 

<वाक्यविन्यास लैंग = जावास्क्रिप्ट> // ईसीएमएस्क्रिप्ट समारोह फू { वार xs = [1, 2, 3, 4]; xs.forEach (फ़ंक्शन (x) {वापसी x;}); वापसी 0; } चेतावनी (फू ); // प्रिंट 0 

उपरोक्त कोड स्निपेट्स अलग तरह से व्यवहार करेंगे क्योंकि स्मॉलटाक  ऑपरेटर और जावास्क्रिप्ट   ऑपरेटर अनुरूप नहीं हैं। ईसीएमएस्क्रिप्ट उदाहरण में,   का एक नया पुनरावृति शुरू करने के लिए आंतरिक समापन को छोड़ देगा   पाश, जबकि स्मालटाक उदाहरण में,   लूप को निरस्त कर देगा और विधि से वापस आ जाएगा.

सामान्य लिस्प एक निर्माण प्रदान करता है जो उपरोक्त कार्यों में से किसी एक को व्यक्त कर सकता है: लिस्प  स्मॉलटाक के रूप में व्यवहार करता है , जबकि लिस्प   जावास्क्रिप्ट के रूप में व्यवहार करता है. इसलिए, स्मॉलटॉक कैप्चर किए गए एस्केप निरंतरता को उस सीमा तक जीवित रहने के लिए संभव बनाता है जिसमें इसे सफलतापूर्वक लागू किया जा सकता है। विचार करना:

<वाक्यविन्यास लैंग = स्मॉलटॉक> गपशप फू ^[ :x | ^x] छड़ | एफ | च := स्वयं फू. एफ मान: 123 त्रुटि! 

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

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

<वाक्यविन्यास लैंग = रूबी>
 * 1) माणिक

डेफ फू f = Proc.new { foo से अंदर की खरीद से वापसी वापसी} f.call # control फू को यहां छोड़ देता है फू से वापसी अंत
 * 1) एक प्रोक का उपयोग कर बंद करें

डेफ बार f = लैम्ब्डा {लैम्ब्डा से रिटर्न रिटर्न} f.call # नियंत्रण यहां बार नहीं छोड़ता है बार से वापसी वापसी अंत
 * 1) लैम्ब्डा का उपयोग करके बंद करें

पुट फू # प्रिंट फू फ्रॉम इनसाइड प्रो बार डालता है # बार से रिटर्न प्रिंट करता है 

दोनों  और   इस उदाहरण में एक क्लोजर बनाने के तरीके हैं, लेकिन इस तरह से बनाए गए क्लोजर के शब्दार्थ इसके संबंध में भिन्न हैं   कथन।

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

<वाक्यविन्यास लैंग = योजना> (कॉल/सीसी कॉल-साथ-वर्तमान-निरंतरता को परिभाषित करें)
 * योजना

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

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

(प्रदर्शन (फू)); प्रिंट अंदर से फू से वापस आते हैं (नई पंक्ति) (प्रदर्शन (बार)); प्रिंट बार से वापस आते हैं 

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

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

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

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

<वाक्यविन्यास प्रकाश लैंग = सी>
 * 1) शामिल <stdio.h>

टाइपपीफ इंट (*fn_int_to_int)(int); // फ़ंक्शन का प्रकार int->int

fn_int_to_int योजक (पूर्णांक संख्या) { इंट ऐड (इंट वैल्यू) { रिटर्न वैल्यू + नंबर; } वापसी और जोड़ें; // और ऑपरेटर यहाँ वैकल्पिक है क्योंकि C में एक फ़ंक्शन का नाम एक पॉइंटर है जो स्वयं की ओर इशारा करता है }

पूर्णांक मुख्य (शून्य) { fn_int_to_int add10 = योजक (10); प्रिंटफ (% डी \ n, 10 (1) जोड़ें); वापसी 0; } </वाक्यविन्यास हाइलाइट>

लेकिन चल रहा है  (और, वैकल्पिक रूप से,  ) में   इसे वैध बनाता है:

<वाक्यविन्यास प्रकाश लैंग = सी>
 * 1) शामिल <stdio.h>

पूर्णांक मुख्य (शून्य) { टाइपपीफ इंट (*fn_int_to_int)(int); // फ़ंक्शन का प्रकार int->int fn_int_to_int योजक (पूर्णांक संख्या) { इंट ऐड (इंट वैल्यू) { रिटर्न वैल्यू + नंबर; } वापसी जोड़ें; } fn_int_to_int add10 = योजक (10); प्रिंटफ (% डी \ n, 10 (1) जोड़ें); वापसी 0; } </वाक्यविन्यास हाइलाइट>

यदि इसे क्रियान्वित किया जाता है तो यह अब प्रिंट करता है  आशा के अनुसार।

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

<वाक्यविन्यास प्रकाश लैंग = जावा> वर्ग गणनाविंडो JFrame का विस्तार करता है { निजी अस्थिर इंट परिणाम; // ...   सार्वजनिक शून्य गणना अलग-अलग थ्रेड (अंतिम यूआरआई यूरी) { // अभिव्यक्ति नया रननेबल {...} 'रननेबल' इंटरफ़ेस को लागू करने वाला एक अनाम वर्ग है। नया सूत्र(           नया रननेबल  {                शून्य रन  {                    // यह अंतिम स्थानीय चर पढ़ सकता है:                    गणना (यूरी);                    // यह संलग्न वर्ग के निजी क्षेत्रों तक पहुँच सकता है:                    परिणाम = परिणाम + 10;                }            }        )।शुरू करना; } } </वाक्यविन्यास हाइलाइट>

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

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

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

<वाक्यविन्यास प्रकाश लैंग = जावा> वर्ग गणनाविंडो JFrame का विस्तार करता है { निजी अस्थिर इंट परिणाम; // ...   सार्वजनिक शून्य गणना अलग-अलग थ्रेड (अंतिम यूआरआई यूरी) { // कोड -> { /* कोड */} एक क्लोजर है। नया थ्रेड ( -> {           गणना (यूरी);            परिणाम = परिणाम + 10;        })।शुरू करना; } } </वाक्यविन्यास हाइलाइट>

स्थानीय वर्ग एक प्रकार के आंतरिक वर्ग हैं जो एक विधि के शरीर के भीतर घोषित किए जाते हैं। जावा आंतरिक कक्षाओं का भी समर्थन करता है जिन्हें एक संलग्न वर्ग के गैर-स्थैतिक सदस्यों के रूप में घोषित किया जाता है। उन्हें आम तौर पर आंतरिक कक्षाओं के रूप में संदर्भित किया जाता है। इन्हें संलग्न वर्ग के शरीर में परिभाषित किया गया है और संलग्न वर्ग के आवृत्ति चरों तक पूर्ण पहुंच है। इन इंस्टेंस वेरिएबल्स के लिए उनके बंधन के कारण, एक विशेष सिंटैक्स का उपयोग करके संलग्न वर्ग के एक उदाहरण के लिए एक स्पष्ट बंधन के साथ एक आंतरिक वर्ग को केवल तत्काल किया जा सकता है। <वाक्यविन्यास प्रकाश लैंग = जावा> पब्लिक क्लास एनक्लोजिंग क्लास { / * आंतरिक वर्ग को परिभाषित करें * / पब्लिक क्लास इनरक्लास { सार्वजनिक पूर्णांक वृद्धि और रिटर्न काउंटर { वापसी काउंटर ++; }   }

निजी इंट काउंटर; {       काउंटर = 0; }

सार्वजनिक int getCounter { वापसी काउंटर; }

सार्वजनिक स्थैतिक शून्य main (String [] args) { 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 के रूप में, जावा प्रथम श्रेणी की वस्तुओं के रूप में कार्यों का समर्थन करता है। इस रूप के लैम्ब्डा भावों को प्रकार का माना जाता है  जहां T डोमेन है और U छवि प्रकार है। इसके साथ व्यंजक कहा जा सकता है   विधि, लेकिन मानक विधि कॉल के साथ नहीं।

<वाक्यविन्यास प्रकाश लैंग = जावा> सार्वजनिक स्थैतिक शून्य main (String [] args) { समारोह <स्ट्रिंग, पूर्णांक> लंबाई = s -> s.length ;

System.out.println (लंबाई। लागू करें (हैलो, दुनिया!)); // 13 प्रिंट करेगा। } </वाक्यविन्यास हाइलाइट>

ब्लॉक (सी, सी ++, ऑब्जेक्टिव-सी 2.0)
Apple Inc. ने C (प्रोग्रामिंग भाषा), C++, ऑब्जेक्टिव-C 2.0 और Mac OS X स्नो लेपर्ड | Mac OS X 10.6 स्नो लेपर्ड और IOS ( सेब) | आईओएस 4.0। ऐप्पल ने जीसीसी और क्लैंग कंपाइलर्स के लिए अपना कार्यान्वयन उपलब्ध कराया।

शाब्दिक ब्लॉक और ब्लॉक करने के लिए पॉइंटर्स को चिह्नित किया गया है. जब ब्लॉक बनाया जाता है तो सामान्य स्थानीय चर मूल्य द्वारा कब्जा कर लिया जाता है, और केवल पढ़ने के लिए ब्लॉक के अंदर होता है। संदर्भ द्वारा कैप्चर किए जाने वाले वेरिएबल्स को चिह्नित किया गया है. जिन ब्लॉकों को उनके द्वारा बनाए गए दायरे से बाहर बने रहने की आवश्यकता है, उन्हें कॉपी करने की आवश्यकता हो सकती है। <वाक्यविन्यास हाइलाइट लैंग = ओबीजेसी> टाइपपीफ इंट (^ इंटब्लॉक) ;

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

इंटब्लॉक एफ = डाउनकाउंटर (5); एनएसएलओजी (@% डी, एफ ); एनएसएलओजी (@% डी, एफ ); एनएसएलओजी (@% डी, एफ ); </वाक्यविन्यास हाइलाइट>

प्रतिनिधि (सी #, वीबी.नेट, डी)
सी शार्प (प्रोग्रामिंग लैंग्वेज) | सी # अनाम तरीके और लैम्ब्डा एक्सप्रेशन क्लोजर का समर्थन करते हैं:

<वाक्यविन्यास प्रकाश लैंग = csharp> var डेटा = नया [] {1, 2, 3, 4}; वार गुणक = 2; var परिणाम = डेटा। चयन करें (x => x * गुणक); </वाक्यविन्यास हाइलाइट>

Visual Basic .NET, जिसमें C# के समान कई भाषा सुविधाएँ हैं, क्लोजर के साथ लैम्ब्डा एक्सप्रेशन का भी समर्थन करता है:

<वाक्यविन्यास लैंग = vb.net> मंद डेटा = {1, 2, 3, 4} मंद गुणक = 2 मंद परिणाम = डेटा। चयन करें (फ़ंक्शन (x) x * गुणक) </वाक्यविन्यास हाइलाइट>

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

<वाक्यविन्यास प्रकाश लैंग = डी> ऑटो टेस्ट 1 { इंट ए = 7; वापसी प्रतिनिधि {वापसी + 3; }; // अनाम प्रतिनिधि निर्माण }

ऑटो टेस्ट 2 { इंट ए = 20; इंट फू {वापसी ए + 5; } // आंतरिक कार्य वापसी और फू; // प्रतिनिधि बनाने का दूसरा तरीका }

शून्य बार { ऑटो डीजी = test1 ; डीजी ; // = 10 // ठीक है, test1.a क्लोजर में है और अभी भी मौजूद है

डीजी = test2 ; डीजी ; // = 25 // ठीक है, test2.a बंद होने की स्थिति में है और अभी भी मौजूद है } </वाक्यविन्यास हाइलाइट>

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

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

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

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

<वाक्यविन्यास लैंग = एफिल> ok_button.click_event.subscribe ( एजेंट (x, y: INTEGER) करते हैं map.country_at_coordinates (x, y).प्रदर्शन अंत ) </वाक्यविन्यास हाइलाइट>

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

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

सी ++ बिल्डर क्लोजर आरक्षित शब्द
Embarcadero C++ Builder फ़ंक्शन पॉइंटर के समान सिंटैक्स वाली विधि को पॉइंटर प्रदान करने के लिए आरक्षित शब्द _ क्लोजर प्रदान करता है। मानक C में आप a लिख सकते हैं typedef निम्नलिखित सिंटैक्स का उपयोग करके फ़ंक्शन प्रकार के सूचक के लिए: इसी प्रकार से आप घोषित कर सकते हैं a typedef निम्नलिखित सिंटैक्स का उपयोग करने वाली विधि के लिए एक सूचक के लिए:<syntaxhighlight lang= c++ > टाइपपीफ शून्य (__closure *TMyMethodPointer) ; </वाक्यविन्यास हाइलाइट>

यह भी देखें

 * बेनामी समारोह
 * ब्लॉक (सी भाषा विस्तार)
 * कमांड पैटर्न
 * जारी
 * करी
 * फंगस की समस्या
 * लैम्ब्डा कैलकुलस
 * आलसी मूल्यांकन
 * आंशिक आवेदन
 * स्पेगेटी स्टैक
 * सिंटैक्टिक क्लोजर
 * मूल्य-स्तरीय प्रोग्रामिंग

बाहरी संबंध

 * 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 expressions).
 * Closures: An article about closures in dynamically typed imperative languages, by Martin Fowler.
 * Collection closure methods: An example of a technical domain where using closures is convenient, by Martin Fowler.
 * Closures: An article about closures in dynamically typed imperative languages, by Martin Fowler.
 * Collection closure methods: An example of a technical domain where using closures is convenient, by Martin Fowler.