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

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

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

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

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

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

अनाम और स्थिर कार्य
अधिक जानकारी: अनाम कार्य और स्थिर कार्य

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

 गैर-स्थानीय चर और समापन

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

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

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

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

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

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

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

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

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

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

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

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

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

आधुनिक अनिवार्य भाषाएं अक्सर अपशिष्ट-संग्रह का समर्थन करती हैं जिससे प्रथम श्रेणी के कार्यों का कार्यान्वयन संभव हो जाता है। प्रथम श्रेणी के कार्यों को अक्सर भाषा के बाद के संशोधनों में समर्थित किया गया है, जिसमें C# 2.0 और एप्पल के खंड विस्तार से C, C++ और ऑब्जेक्टिव -C सम्मिलित हैं। C++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