क्या बिना राज्य के * किसी * कार्यक्रम कार्य को व्यक्त किया जा सकता है?


13

यह एक सैद्धांतिक सवाल है, लेकिन अब जो कुछ भी मुझे महसूस हो रहा है उसमें प्रोग्रामिंग के कई वर्षों के बाद "सामान्य" अनिवार्य तकनीक है, मुख्य रूप से C ++ का उपयोग करते हुए, मैंने कार्यात्मक प्रोग्रामिंग की इस दूसरी दुनिया की खोज की है, जिसे मैंने गलती से जावास्क्रिप्ट सीखने के दौरान गलती से ठोकर खाई थी।

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

यह एक पेचीदा विचार है और मुझे यह स्वीकार करना चाहिए कि कार्यात्मक प्रोग्रामिंग में एक स्पष्टता और लालित्य है जिसने वास्तव में मेरे दिमाग को उड़ा दिया है।


1
एक प्रासंगिक StackOverflow उत्तर: stackoverflow.com/questions/3722084/…
jfriend00

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

6
यदि आप राज्य पर चर्चा करना चाहते हैं; स्पष्ट रूप से राज्य की आवश्यकता है, यदि केवल कार्यक्रम के लिए ही। ऐसा लगता है कि आप उत्परिवर्ती बनाम अपरिवर्तनीय स्थिति के बारे में सोच रहे हैं - आप यह इंगित करना चाह सकते हैं कि आप प्रश्न में क्या मतलब है।
बिली ओनेल

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

जवाबों:


17

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

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


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

3
लैम्ब्डा कैलकुलस की अवस्था है; इसकी अड़चन यह है कि राज्य अपरिवर्तनीय है। अपरिवर्तनीय स्थिति अभी भी राज्य है। लंबोदर सहित कार्यों के पैरामीटर, अभी भी राज्य हैं; संभवत: आप चाहते हैं कि एक फ़ंक्शन के पास अलग-अलग व्यवहार के लिए अलग-अलग पैरामीटर हों।
बिली ओनेल

@emilio यह बताते हुए कि समस्या के समतुल्य राज्य आधारित समाधान है (जैसा कि आप वर्णन करते हैं) इस बात का प्रमाण नहीं है कि उस समाधान का कोई स्टेटलेस संस्करण मौजूद नहीं है।
बिली ओनेल

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

1
@EmilioGaravglia: एक समय में अनिवार्य प्रोग्रामिंग में राज्य मेमोरी कॉन्फ़िगरेशन है, यहां पैरामीटर स्पेस सभी संभव मेमोरी मानों द्वारा दिया जाता है और एक समय में स्टेट एक कॉन्फ़िगरेशन होता है (ट्यूरिंग मशीन का बैंड)। लैम्ब्डा कैलकुलस में प्रोग्राम लिखते समय मेमोरी फ़ील्ड जैसी कोई प्रत्यक्ष इकाई नहीं होती है। कार्यक्रम निष्पादन लैम्ब्डा परिवर्तनों का अनुप्रयोग है। मध्यवर्ती चरण "राज्य" के सदृश हो सकते हैं, फिर भी वे समान मूल्य के समतुल्य भाव हैं। मूल्यांकन के दौरान कुछ भी नहीं बदलता है, भावों को फिर से लिखा जाता है और "सरल" रूप में संसाधित किया जाता है।
wirbel

14

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

चाहे आपके पास "याद" करने के लिए कुछ हो या जो आपने किया था उस पर निर्भर करता है, आपके पास एक राज्य है।

बिना राज्य वाली प्रणाली "गतिशील" नहीं है: यह सिर्फ एक दहनशील कार्य है। इसका कोई राज्य नहीं हो सकता है, लेकिन अलग-अलग परिणाम उत्पन्न करते हैं- किसी तरह की आपूर्ति के लिए एक राज्य की आवश्यकता होती है।

अब, आपके द्वारा निर्दिष्ट कम्प्यूटेशनल मॉडल के आधार पर, एक राज्य को स्पष्ट रूप से (चर के रूप में) या अंतर्निहित रूप से ("वापसी पते" के रूप में) का प्रतिनिधित्व किया जा सकता है।

जब आप करते हैं तो fna(fnb(x))आप fnb को एक राज्य दे रहे हैं कि बदले में fna के लिए एक राज्य का उत्पादन करेगा। यह इस तथ्य के कारण है कि xfnb को कॉल करने से पहले मौजूद है (इसलिए, यह स्वयं "अतीत" से आता है)।

यह "राज्य के बाहर निकलने" या "राज्य के अस्तित्व में न होने" की बात नहीं है। यह "आई केयर" या "आई नॉट" का मैटर है।


0

राज्य का मतलब वर्तमान उत्तेजना के प्रति प्रतिक्रिया करने की क्षमता है जो अतीत की उत्तेजनाओं पर निर्भर करता है, न कि केवल वर्तमान उत्तेजना के आधार पर।

विशुद्ध रूप से कार्यात्मक कार्यक्रम केवल कार्य हैं। इस प्रकार व्यावहारिक अनुप्रयोगों के लिए विशुद्ध रूप से कार्यात्मक कार्यक्रम एक जोड़ी (old_state * present_stimulus) को इनपुट करता है और एक जोड़ी (new_state * present_response) को आउटपुट करता है। अगली उत्तेजना के लिए प्रतीक्षा करने और राज्य को प्रचारित करने के लिए एक बाहरी, राज्यपूर्ण "लूपर" की आवश्यकता होती है।

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

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


0

जब तक आपको बाहरी दुनिया से बातचीत नहीं करनी है, आप स्पष्ट रूप से परिवर्तनशील स्थिति से बच सकते हैं।

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

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

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


0

इस बारे में सोचें कि आप राज्य के बिना प्रोग्रामिंग भाषा में "राज्य मशीन" कैसे लागू करेंगे।

आप शायद वास्तव में ऐसा कर सकते हैं, लेकिन आप भंडारण के रूप में फ़ंक्शन नामों का उपयोग करना समाप्त करेंगे। इस तरह से gobblyday के साथ समाप्त हो रहा है:

if (sm.atBegining()) sm.start() else if (sm.done()) sm.stop() ) else sm.progress()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.