प्रथम श्रेणी फंक्शन

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

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

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

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

अनाम और नेस्टेड कार्य
अज्ञात कार्यों का समर्थन करने वाली भाषाओं में, हम इस तरह के फ़ंक्शन को उच्च-क्रम फ़ंक्शन के तर्क के रूप में पास कर सकते हैं: ऐसी भाषा में जो अज्ञात कार्यों का समर्थन नहीं करती है, हमें इसे इसके बजाय नाम से बांधना होगा:

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

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

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

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

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


 * गहन समानता: आकस्मिक समानता के तहत, दो कार्यों f और g को समान माना जाता है यदि उनकी आंतरिक संरचना समान हो। इस तरह की समानता व्याख्या की गई भाषाओं में कार्य निकायों के स्रोत कोड (जैसे व्याख्या किए गए लिस्प 1.5 में) या संकलित भाषाओं में वस्तु कोड  की तुलना करके कार्यान्वित की जा सकती है। आकस्मिक समानता का तात्पर्य विस्तारात्मक समानता से है (यह मानते हुए कि कार्य नियतात्मक हैं और उनमें कोई छिपा हुआ इनपुट नहीं है, जैसे कि  कार्यक्रम गणक  या एक परिवर्तनशील वैश्विक चर।)


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

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

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

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

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

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

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

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


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


 * अजगर
 * स्पष्ट आंशिक आवेदन के साथ  संस्करण 2.5 के बाद से, और   संस्करण 2.6 के बाद से।


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

यह भी देखें

 * निष्क्रियता
 * eval
 * प्रथम श्रेणी का संदेश
 * कप्पा कलन - एक औपचारिकता जो प्रथम श्रेणी के कार्यों को बाहर करती है
 * आदमी या लड़का परीक्षण
 * आंशिक आवेदन

संदर्भ

 * Leonidas Fegaras. "Functional Languages and Higher-Order Functions". CSE5317/CSE4305: Design and Construction of Compilers. University of Texas at Arlington.

बाहरी संबंध

 * First-class functions on Rosetta Code.
 * Higher order functions at IBM developerWorks