इस उत्तर के प्रयोजनों के लिए मैं "विशुद्ध रूप से कार्यात्मक भाषा" को एक कार्यात्मक भाषा के रूप में परिभाषित करता हूं जिसमें फ़ंक्शन संदर्भित रूप से पारदर्शी होते हैं, अर्थात समान तर्कों के साथ एक ही फ़ंक्शन को कई बार कॉल करना हमेशा समान परिणाम देगा। मेरा मानना है कि विशुद्ध रूप से कार्यात्मक भाषा की सामान्य परिभाषा है।
शुद्ध कार्यात्मक प्रोग्रामिंग भाषाएं साइड इफेक्ट्स की अनुमति नहीं देती हैं (और इसलिए अभ्यास में बहुत कम उपयोग होता है क्योंकि किसी भी उपयोगी कार्यक्रम के साइड इफेक्ट्स होते हैं, जैसे जब यह बाहरी दुनिया के साथ बातचीत करता है)।
रेफ़रेंशियल ट्रांसपेरेंसी को प्राप्त करने का सबसे आसान तरीका वास्तव में साइड इफेक्ट्स को खत्म करना होगा और वास्तव में ऐसी भाषाएं हैं जिनमें ऐसा होता है (ज्यादातर डोमेन विशिष्ट वाले)। हालांकि यह निश्चित रूप से एकमात्र तरीका नहीं है और सबसे सामान्य उद्देश्य विशुद्ध रूप से कार्यात्मक भाषा (हास्केल, क्लीन, ...) साइड इफेक्ट की अनुमति देते हैं।
यह भी कहना कि साइड इफेक्ट्स के बिना एक प्रोग्रामिंग भाषा व्यवहार में बहुत कम उपयोग होती है, मैं वास्तव में उचित नहीं लगता - निश्चित रूप से डोमेन विशिष्ट भाषाओं के लिए नहीं, लेकिन सामान्य प्रयोजन की भाषाओं के लिए भी, मुझे लगता है कि साइड इफेक्ट प्रदान किए बिना एक भाषा काफी उपयोगी हो सकती है । शायद कंसोल अनुप्रयोगों के लिए नहीं, लेकिन मुझे लगता है कि जीयूआई अनुप्रयोगों को बिना किसी साइड-इफ़ेक्ट के लागू किया जा सकता है, कहते हैं, कार्यात्मक प्रतिक्रियाशील प्रतिमान।
बिंदु 1 के बारे में, आप पर्यावरण के साथ विशुद्ध रूप से कार्यात्मक भाषाओं में बातचीत कर सकते हैं लेकिन आपको कोड (फ़ंक्शन) को स्पष्ट रूप से चिह्नित करना होगा जो उन्हें पेश करता है (उदाहरण के लिए हास्केल में मोनैडिक प्रकार के माध्यम से)।
यह थोड़ा सरल है। बस एक ऐसी प्रणाली होने पर जहां साइड-इफ़ेक्टिंग फ़ंक्शंस को इस तरह से चिह्नित किया जाना चाहिए (सी ++ में कॉन्स्ट-करेक्शन के समान, लेकिन सामान्य साइड-इफ़ेक्ट के साथ) संदर्भात्मक पारदर्शिता सुनिश्चित करने के लिए पर्याप्त नहीं है। आपको यह सुनिश्चित करने की आवश्यकता है कि एक प्रोग्राम एक ही तर्कों के साथ कई बार किसी फ़ंक्शन को कॉल नहीं कर सकता है और विभिन्न परिणाम प्राप्त कर सकता है। आप या तो ऐसा कर सकते हैं जैसे चीजें बनाकरreadLine
कुछ ऐसा हो जो कोई फ़ंक्शन न हो (जो कि हास्केल आईओ मोनड के साथ करता है) या आप एक ही तर्क के साथ कई बार साइड-इफ़ेक्टिंग फ़ंक्शन को कॉल करना असंभव बना सकते हैं (यह वही है जो क्लीन करता है)। बाद के मामले में कंपाइलर यह सुनिश्चित करेगा कि हर बार जब आप किसी साइड-इफ़ेक्टिंग फंक्शन को कॉल करते हैं, तो आप एक ताज़ा तर्क के साथ ऐसा करते हैं, और यह किसी भी प्रोग्राम को अस्वीकार कर देता है जहाँ आप एक साइड-इफ़ेक्टिंग फंक्शन को दो बार पास करते हैं।
शुद्ध कार्यात्मक प्रोग्रामिंग भाषाएं एक प्रोग्राम लिखने की अनुमति नहीं देती हैं जो राज्य को बनाए रखता है (जो प्रोग्रामिंग को बहुत अजीब बनाता है क्योंकि कई एप्लिकेशन में आपको राज्य की आवश्यकता होती है)।
फिर, एक विशुद्ध रूप से कार्यात्मक भाषा उत्परिवर्ती राज्य को बहुत अच्छी तरह से अस्वीकार कर सकती है, लेकिन यह निश्चित रूप से शुद्ध होना संभव है और अभी भी परिवर्तनशील राज्य है, यदि आप इसे उसी तरह से लागू करते हैं जैसा कि मैंने ऊपर दिए गए साइड-इफेक्ट्स के साथ वर्णित किया है। वास्तव में उत्परिवर्तनीय स्थिति साइड-इफेक्ट का दूसरा रूप है।
उस ने कहा, कार्यात्मक प्रोग्रामिंग भाषा निश्चित रूप से उत्परिवर्तनीय स्थिति - शुद्ध लोगों को विशेष रूप से हतोत्साहित करती हैं। और मुझे नहीं लगता है कि यह प्रोग्रामिंग अजीब बनाता है - काफी विपरीत। कभी-कभी (लेकिन यह सब अक्सर नहीं) उत्परिवर्तनीय स्थिति को प्रदर्शन या स्पष्टता को खोए बिना टाला नहीं जा सकता है (यही वजह है कि हास्केल जैसी भाषाओं में उत्परिवर्तित राज्य के लिए सुविधाएं हैं), लेकिन सबसे अधिक बार यह हो सकता है।
अगर वे गलत धारणाएं हैं, तो वे कैसे आए?
मुझे लगता है कि बहुत से लोग बस "एक फ़ंक्शन को एक ही परिणाम का उत्पादन करना चाहिए जब उसी तर्क के साथ बुलाया जाता है" और इससे निष्कर्ष निकाला जाए कि कुछ ऐसा लागू करना संभव नहीं है जैसे readLine
या कोड जो कि उत्परिवर्तनीय स्थिति बनाए रखता है। तो वे बस "धोखा" के बारे में पता नहीं है कि विशुद्ध रूप से कार्यात्मक भाषाओं को संदर्भित पारदर्शिता को तोड़ने के बिना इन चीजों को पेश करने के लिए उपयोग कर सकते हैं।
साथ ही उत्परिवर्तनीय अवस्था कार्यात्मक भाषाओं में भारी रूप से हतोत्साहित करती है, इसलिए यह पूरी तरह से कार्यात्मक लोगों में इसकी अनुमति नहीं है।
क्या आप एक (संभवतः छोटा) कोड स्निपेट लिखकर हास्केल मुहावरेदार तरीके को दिखा सकते हैं (1) साइड इफेक्ट्स को लागू करने और (2) राज्य के साथ एक संगणना लागू करने के लिए?
यहाँ छद्म-हास्केल में एक एप्लिकेशन है जो उपयोगकर्ता से एक नाम पूछता है और उसे बधाई देता है। स्यूडो-हास्केल एक ऐसी भाषा है जिसका मैंने अभी आविष्कार किया है, जिसमें हास्केल की आईओ प्रणाली है, लेकिन अधिक पारंपरिक वाक्यविन्यास, अधिक वर्णनात्मक फ़ंक्शन नामों का उपयोग किया गया है और कोई भी do
टिप्पणी नहीं है (जैसा कि सिर्फ इस बात से विचलित होगा कि आईओ मोनड कैसे काम करता है):
greet(name) = print("Hello, " ++ name ++ "!")
main = composeMonad(readLine, greet)
यहाँ सुराग यह है कि readLine
एक प्रकार का मान है IO<String>
और composeMonad
एक फ़ंक्शन है जो प्रकार का तर्क लेता है IO<T>
(कुछ प्रकार के लिए T
) और दूसरा तर्क एक फ़ंक्शन है जो प्रकार का तर्क लेता है T
और प्रकार का मान लौटाता है IO<U>
(कुछ प्रकार के लिए U
)। print
एक फ़ंक्शन है जो एक स्ट्रिंग लेता है और प्रकार का मान लौटाता है IO<void>
।
प्रकार IO<A>
का एक मान एक मान है जो किसी दिए गए कार्य को "एनकोड" करता है जो प्रकार के मूल्य का उत्पादन करता है A
। composeMonad(m, f)
एक नए IO
मूल्य का उत्पादन करता है, जो की कार्रवाई के m
बाद कार्रवाई करता है f(x)
, जहां x
का मूल्य कार्रवाई का उत्पादन करता है m
।
म्यूटेबल स्थिति इस तरह दिखाई देगी:
counter = mutableVariable(0)
increaseCounter(cnt) =
setIncreasedValue(oldValue) = setValue(cnt, oldValue + 1)
composeMonad(getValue(cnt), setIncreasedValue)
printCounter(cnt) = composeMonad( getValue(cnt), print )
main = composeVoidMonad( increaseCounter(counter), printCounter(counter) )
यहां mutableVariable
एक फ़ंक्शन है जो किसी भी प्रकार का मूल्य लेता है T
और उत्पादन करता है MutableVariable<T>
। फ़ंक्शन getValue
लेता है MutableVariable
और रिटर्न करता IO<T>
है जो इसके वर्तमान मूल्य का उत्पादन करता है। setValue
एक MutableVariable<T>
और एक लेता है और एक T
रिटर्न देता है जो IO<void>
मान सेट करता है। composeVoidMonad
रूप में ही है composeMonad
, सिवाय इसके कि पहले तर्क एक है IO
कि एक समझदार मूल्य और दूसरा तर्क का उत्पादन नहीं करता एक और इकाई, नहीं एक समारोह है कि रिटर्न एक इकाई है।
हास्केल में कुछ संश्लिष्ट चीनी होती है, जो इस पूरे क्रम को कम दर्दनाक बनाती है, लेकिन यह अभी भी स्पष्ट है कि उत्परिवर्तनीय स्थिति ऐसी चीज है जो भाषा वास्तव में आपको नहीं करना चाहती है।