संदर्भात्मक पारदर्शिता: Difference between revisions

From Vigyanwiki
No edit summary
No edit summary
Line 2: Line 2:
{{About|प्रोग्रामिंग भाषा सिद्धांत में संदर्भात्मक पारदर्शिता|भाषाविज्ञान और दर्शनशास्त्र में इसका उपयोग|अपारदर्शी संदर्भ}}
{{About|प्रोग्रामिंग भाषा सिद्धांत में संदर्भात्मक पारदर्शिता|भाषाविज्ञान और दर्शनशास्त्र में इसका उपयोग|अपारदर्शी संदर्भ}}


[[कंप्यूटर विज्ञान]] में, '''संदर्भात्मक पारदर्शिता''' और '''संदर्भात्मक अस्पष्टता''' [[कंप्यूटर प्रोग्राम]] के कुछ हिस्सों के गुण हैं। किसी अभिव्यक्ति को ''संदर्भात्मक पारदर्शी'' कहा जाता है यदि इसे प्रोग्राम के व्यवहार को बदले बिना इसके संबंधित मान (और इसके विपरीत) से बदला जा सकता है।<ref>{{cite book|title=प्रोग्रामिंग भाषाओं में अवधारणाएँ|author=John C. Mitchell|year=2002|publisher=Cambridge University Press|page=[https://books.google.com/books?id=7Uh8XGfJbEIC&dq=referential+transparency&pg=PA78 78]}}</ref> इसके लिए आवश्यक है कि अभिव्यक्ति शुद्ध हो - समान इनपुट के लिए इसका मूल्य समान होना चाहिए और इसके मूल्यांकन का कोई दुष्प्रभाव नहीं होना चाहिए। एक अभिव्यक्ति जो संदर्भित रूप से पारदर्शी नहीं है उसे '''संदर्भित अपारदर्शी''' कहा जाता है।
[[कंप्यूटर विज्ञान]] में, '''संदर्भात्मक पारदर्शिता''' और '''संदर्भात्मक अस्पष्टता''' [[कंप्यूटर प्रोग्राम]] के कुछ हिस्सों के गुण हैं। किसी अभिव्यक्ति को ''संदर्भात्मक पारदर्शी'' कहा जाता है यदि इसे प्रोग्राम के व्यवहार को बदले बिना इसके संबंधित मान (और इसके विपरीत) से बदला जा सकता है।<ref>{{cite book|title=प्रोग्रामिंग भाषाओं में अवधारणाएँ|author=John C. Mitchell|year=2002|publisher=Cambridge University Press|page=[https://books.google.com/books?id=7Uh8XGfJbEIC&dq=referential+transparency&pg=PA78 78]}}</ref> इसके लिए आवश्यक है कि अभिव्यक्ति शुद्ध हो - समान इनपुट के लिए इसका मूल्य समान होना चाहिए और इसके मूल्यांकन का कोई अनुषंगी प्रभाव नहीं होना चाहिए। एक अभिव्यक्ति जो संदर्भित रूप से पारदर्शी नहीं है उसे '''संदर्भित अपारदर्शी''' कहा जाता है।


गणित में, गणितीय [[फ़ंक्शन (गणित)|फ़ंक्शन]] का गठन क्या होता है, इसकी परिभाषा के अनुसार, सभी फ़ंक्शन अनुप्रयोग संदर्भात्मक रूप से पारदर्शी होते हैं। हालाँकि, प्रोग्रामिंग में ऐसा हमेशा नहीं होता है, जहाँ भ्रामक अर्थों से बचने के लिए शब्द ''प्रक्रिया'' और ''विधि'' का उपयोग किया जाता है। कार्यात्मक प्रोग्रामिंग की एक परिभाषित विशेषता यह है कि यह केवल संदर्भात्मक रूप से पारदर्शी कार्यों की अनुमति देती है। अन्य [[प्रोग्रामिंग भाषा|प्रोग्रामिंग भाषाएँ]] संदर्भात्मक पारदर्शिता की चुनिंदा प्रत्याभूति देने के साधन प्रदान कर सकती हैं। कुछ कार्यात्मक प्रोग्रामिंग भाषाएँ सभी कार्यों के लिए संदर्भित पारदर्शिता लागू करती हैं।
गणित में, गणितीय [[फ़ंक्शन (गणित)|फ़ंक्शन]] का गठन क्या होता है, इसकी परिभाषा के अनुसार, सभी फ़ंक्शन अनुप्रयोग संदर्भात्मक रूप से पारदर्शी होते हैं। हालाँकि, प्रोग्रामिंग में ऐसा हमेशा नहीं होता है, जहाँ भ्रामक अर्थों से बचने के लिए शब्द ''प्रक्रिया'' और ''विधि'' का उपयोग किया जाता है। कार्यात्मक प्रोग्रामिंग की एक परिभाषित विशेषता यह है कि यह केवल संदर्भात्मक रूप से पारदर्शी कार्यों की अनुमति देती है। अन्य [[प्रोग्रामिंग भाषा|प्रोग्रामिंग भाषाएँ]] संदर्भात्मक पारदर्शिता की चुनिंदा प्रत्याभूति देने के साधन प्रदान कर सकती हैं। कुछ कार्यात्मक प्रोग्रामिंग भाषाएँ सभी कार्यों के लिए संदर्भित पारदर्शिता लागू करती हैं।
Line 9: Line 9:


== इतिहास ==
== इतिहास ==
ऐसा प्रतीत होता है कि इस अवधारणा की उत्पत्ति [[अल्फ्रेड नॉर्थ व्हाइटहेड]] और [[बर्ट्रेंड रसेल]] की [[गणितीय सिद्धांत]] (1910-13) में हुई थी।<ref>{{cite book | url=https://archive.org/details/PrincipiaMathematicaVolumeI | author1=Alfred North Whitehead | author2= Bertrand Russell | title=गणितीय सिद्धांत| volume=1 | publisher=Cambridge University Press | edition=2nd | year=1927 }} Here: p.665. According to Quine, the term originates from there.</ref> इसे [[विलार्ड वान ऑरमैन क्विन]] द्वारा [[विश्लेषणात्मक दर्शन]] में अपनाया गया था। वर्ड एंड ऑब्जेक्ट (1960) के §30 में क्विन यह परिभाषा देता है:
ऐसा प्रतीत होता है कि इस अवधारणा की उत्पत्ति [[अल्फ्रेड नॉर्थ व्हाइटहेड|ल्फ्रेड नॉर्थ व्हाइटहेड]] और [[बर्ट्रेंड रसेल]] की प्रिंसिपिया मैथमैटिका (1910-13) में हुई थी।<ref>{{cite book | url=https://archive.org/details/PrincipiaMathematicaVolumeI | author1=Alfred North Whitehead | author2= Bertrand Russell | title=गणितीय सिद्धांत| volume=1 | publisher=Cambridge University Press | edition=2nd | year=1927 }} Here: p.665. According to Quine, the term originates from there.</ref> इसे विश्लेषणात्मक दर्शनशास्र में [[विलार्ड वान ऑरमैन क्विन]] द्वारा अपनाया गया था। वर्ड एंड ऑब्जेक्ट (1960) के §30 में क्वीन यह परिभाषा देती है:
<ब्लॉककोट>
 
रोकथाम का एक तरीका φ संदर्भात्मक रूप से पारदर्शी है, यदि, जब भी एक एकल शब्द t की घटना किसी शब्द या वाक्य ψ(t) में पूरी तरह से संदर्भित होती है, तो यह युक्त शब्द या वाक्य φ(ψ(t)) में भी पूरी तरह से संदर्भित होती है।
नियंत्रण का एक तरीका φ संदर्भात्मक रूप से पारदर्शी है, यदि, जब भी एक एकल शब्द t की घटना किसी शब्द या वाक्य ψ(t) में विशुद्ध रूप से संदर्भित होती है, तो यह युक्त शब्द या वाक्य φ(ψ(t)) में भी पूरी तरह से संदर्भात्मक होती है।
</ब्लॉककोट>
 
यह शब्द अपने समकालीन कंप्यूटर विज्ञान के उपयोग में, प्रोग्रामिंग भाषाओं में [[चर (कंप्यूटर विज्ञान)]] की चर्चा में, [[क्रिस्टोफर स्ट्रेची]] के व्याख्यान नोट्स के मौलिक सेट प्रोग्रामिंग भाषाओं में मौलिक अवधारणाओं (1967) में दिखाई दिया। व्याख्यान नोट्स में ग्रंथ सूची में क्वीन के [[शब्द और वस्तु]] का संदर्भ दिया गया।
यह शब्द अपने ''समकालीन कंप्यूटर'' विज्ञान के उपयोग में, प्रोग्रामिंग भाषाओं में चर की चर्चा में, क्रिस्टोफर स्ट्रेची के व्याख्यान नोट्स के मौलिक सेट प्रोग्रामिंग भाषाओं में मौलिक अवधारणाओं (1967) में दिखाई दिया। व्याख्यान नोट्स में ग्रंथ सूची में क्विन के शब्द और वस्तु का संदर्भ दिया गया है।


== उदाहरण और प्रति उदाहरण ==
== उदाहरण और प्रति उदाहरण ==
यदि अभिव्यक्ति में शामिल सभी फ़ंक्शन शुद्ध फ़ंक्शन हैं, तो अभिव्यक्ति संदर्भात्मक रूप से पारदर्शी है।
यदि अभिव्यक्ति में शामिल सभी कार्य प्यूर फंक्शन हैं, तो अभिव्यक्ति संदर्भित रूप से पारदर्शी है।


एक ऐसे फ़ंक्शन पर विचार करें जो किसी स्रोत से इनपुट लौटाता है। स्यूडोकोड में, इस फ़ंक्शन के लिए कॉल हो सकती है <code>GetInput(Source)</code> कहाँ <code>Source</code> किसी विशेष डिस्क फ़ाइल, [[कंप्यूटर कीबोर्ड]] आदि की पहचान कर सकता है, यहाँ तक कि समान मानों के साथ भी <code>Source</code>, क्रमिक रिटर्न मान भिन्न होंगे। इसलिए, कार्य करें <code>GetInput()</code> न तो नियतिवादी है और न ही संदर्भात्मक रूप से पारदर्शी है।
किसी ऐसे फ़ंक्शन पर विचार करें जो किसी स्रोत से इनपुट वापस करता है। स्यूडोकोड में, इस फ़ंक्शन के लिए एक कॉल <code>GetInput(Source)</code> हो सकती है जहां <code>Source</code> एक विशेष डिस्क फ़ाइल, [[कंप्यूटर कीबोर्ड|कीबोर्ड]] इत्यादि की पहचान कर सकता है। यहां तक कि <code>Source</code>के समान मानों के साथ भी, क्रमिक रिटर्न मान भिन्न होंगे। इसलिए, फ़ंक्शन <code>GetInput()</code> न तो नियतिवादी है और न ही संदर्भात्मक रूप से पारदर्शी है।


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


अंकगणितीय परिचालन संदर्भात्मक रूप से पारदर्शी हैं: <code>5 * 5</code> द्वारा प्रतिस्थापित किया जा सकता है <code>25</code>, उदाहरण के लिए। वास्तव में, गणितीय अर्थ में सभी कार्य संदर्भात्मक रूप से पारदर्शी हैं: <code>sin(x)</code> पारदर्शी है, क्योंकि यह हमेशा प्रत्येक विशेष के लिए समान परिणाम देगा <code>x</code>.
अंकगणितीय संक्रियाएं संदर्भात्मक रूप से पारदर्शी होती हैं: उदाहरण के लिए, <code>5 * 5</code> को <code>25</code> से बदला जा सकता है। वास्तव में, गणितीय अर्थ में सभी फ़ंक्शन संदर्भात्मक रूप से पारदर्शी हैं: <code>sin(x)</code> पारदर्शी है क्योंकि यह हमेशा प्रत्येक विशेष <code>x</code>के लिए समान परिणाम देगा।


पुनर्नियुक्ति पारदर्शी नहीं हैं. उदाहरण के लिए, [[सी (प्रोग्रामिंग भाषा)]] अभिव्यक्ति <code>x = x + 1</code> वेरिएबल को निर्दिष्ट मान बदल देता है <code>x</code>. यह मानते हुए <code>x</code> प्रारंभ में मूल्य है <code>10</code>, अभिव्यक्ति उपज के दो लगातार मूल्यांकन, क्रमशः, <code>11</code> और <code>12</code>. स्पष्ट रूप से, प्रतिस्थापित करना <code>x = x + 1</code> किसी के साथ <code>11</code> या <code>12</code> भिन्न अर्थ वाला एक प्रोग्राम देता है, और इसलिए अभिव्यक्ति संदर्भात्मक रूप से पारदर्शी नहीं है। हालाँकि, जैसे किसी फ़ंक्शन को कॉल करना {{code|int plusone(int x) { return x + 1; }|c}} पारदर्शी है, क्योंकि यह इनपुट को अंतर्निहित रूप से नहीं बदलेगा <code>x</code> और इस प्रकार इसका कोई दुष्प्रभाव (कंप्यूटर विज्ञान) नहीं है।
पुनर्नियुक्तियाँ पारदर्शी नहीं हैं. उदाहरण के लिए, C एक्सप्रेशन <code>x = x + 1</code>, वेरिएबल <code>x</code>को निर्दिष्ट मान को बदल देता है। यह मानते हुए कि प्रारंभ में<code>x</code>का मान <code>10</code> है, अभिव्यक्ति के दो लगातार मूल्यांकन क्रमशः <code>11</code> और <code>12</code> प्राप्त करते हैं। स्पष्ट रूप से, <code>x = x + 1</code> को <code>11</code> या <code>12</code> के साथ प्रतिस्थापित करने से एक अलग अर्थ वाला एक प्रोग्राम मिलता है, और इसलिए अभिव्यक्ति संदर्भात्मक रूप से पारदर्शी नहीं है . हालाँकि, किसी फ़ंक्शन को कॉल करना जैसे {{code|int plusone(int x) { return x + 1; }|c}} पारदर्शी है, क्योंकि यह इनपुट <code>x</code> को अंतर्निहित रूप से नहीं बदलेगा और इस प्रकार इसका कोई अनुषंगी प्रभाव नहीं होगा।


<code>today()</code> पारदर्शी नहीं है, जैसे कि आप इसका मूल्यांकन करते हैं और इसे इसके मूल्य से प्रतिस्थापित करते हैं (मान लीजिए, <code>"Jan 1, 2001"</code>), यदि आप इसे कल चलाएंगे तो आपको वैसा परिणाम नहीं मिलेगा जैसा आपको मिलेगा। ऐसा इसलिए है क्योंकि यह एक [[राज्य (कंप्यूटर विज्ञान)]] (तारीख) पर निर्भर करता है।
<code>today()</code> पारदर्शी नहीं है, जैसे कि आप इसका मूल्यांकन करते हैं और इसे इसके मूल्य से प्रतिस्थापित करते हैं (मान लीजिए, <code>"Jan 1, 2001"</code>), यदि आप इसे कल चलाएंगे तो आपको वैसा परिणाम नहीं मिलेगा जैसा आपको मिलेगा। ऐसा इसलिए है क्योंकि यह एक [[राज्य (कंप्यूटर विज्ञान)]] (तारीख) पर निर्भर करता है।


[[हास्केल (प्रोग्रामिंग भाषा)]] जैसी बिना किसी दुष्प्रभाव वाली भाषाओं में, हम बराबर के स्थान पर बराबर का उपयोग कर सकते हैं: यानी यदि <code>x == y</code> तब <code>f(x) == f(y)</code>. यह एक ऐसी संपत्ति है जिसे [[अविवेकी की पहचान]] के रूप में भी जाना जाता है। साइड-इफेक्ट वाली भाषाओं के लिए ऐसे गुणों को सामान्य रूप से लागू करने की आवश्यकता नहीं है। फिर भी, ऐसे दावों को तथाकथित निर्णयात्मक समानता तक सीमित करना महत्वपूर्ण है, जो कि सिस्टम द्वारा परीक्षण किए गए शब्दों की समानता है, जिसमें प्रकारों के लिए उपयोगकर्ता द्वारा परिभाषित समकक्षता शामिल नहीं है। उदाहरण के लिए, यदि <code>B f(A x)</code> और प्रकार <code>A</code> समानता की धारणा को खत्म कर दिया है, उदा. सभी पदों को समान बनाने पर यह संभव है <code>x == y</code> और फिर भी खोजें <code>f(x) != f(y)</code>. ऐसा इसलिए है क्योंकि हास्केल (प्रोग्रामिंग भाषा) जैसी प्रणालियां यह सत्यापित नहीं करती हैं कि उपयोगकर्ता-परिभाषित समतुल्य संबंधों वाले प्रकारों पर परिभाषित कार्यों को उस समतुल्यता के संबंध में अच्छी तरह से परिभाषित किया जाना चाहिए। इस प्रकार संदर्भात्मक पारदर्शिता तुल्यता संबंधों के बिना प्रकारों तक सीमित है। उदाहरण के लिए, उपयोगकर्ता-परिभाषित तुल्यता संबंधों के लिए संदर्भात्मक पारदर्शिता का विस्तार मार्टिन-लोफ पहचान प्रकार के साथ किया जा सकता है, लेकिन इसके लिए एग्डा (प्रोग्रामिंग भाषा), [[कॉक]] या [[इदरीस (प्रोग्रामिंग भाषा)]] जैसी निर्भरता से टाइप की गई प्रणाली की आवश्यकता होती है।
[[हास्केल (प्रोग्रामिंग भाषा)|हास्केल]] जैसी बिना किसी अनुषंगी प्रभाव वाली भाषाओं में, हम बराबर के स्थान पर बराबर का उपयोग कर सकते हैं: यानी यदि <code>x == y</code> तो <code>f(x) == f(y)</code>है। यह एक ऐसा गुण है जिसे अविभाज्य समरूपता के रूप में भी जाना जाता है। अनुषंगी प्रभाव वाली भाषाओं के लिए ऐसे गुणों को सामान्य रूप से लागू करने की आवश्यकता नहीं है। फिर भी, ऐसे दावों को तथाकथित निर्णयात्मक समानता तक सीमित करना महत्वपूर्ण है, जो कि सिस्टम द्वारा परीक्षण किए गए शब्दों की समानता है, जिसमें प्रकारों के लिए उपयोगकर्ता द्वारा परिभाषित समकक्षता शामिल नहीं है। उदाहरण के लिए, यदि बी एफ (ए एक्स) और प्रकार ए ने समानता की धारणा को ओवरराइड कर दिया है, उदाहरण के लिए सभी पदों को समान बनाने पर,<code>x == y</code> होना संभव है और फिर भी <code>f(x) != f(y)</code> ज्ञात करना संभव है। ऐसा इसलिए है क्योंकि हास्केल जैसी प्रणालियाँ यह सत्यापित नहीं करती हैं कि उपयोगकर्ता-परिभाषित तुल्यता संबंधों वाले प्रकारों पर परिभाषित कार्यों को उस तुल्यता के संबंध में अच्छी तरह से परिभाषित किया जाना चाहिए। इस प्रकार संदर्भात्मक पारदर्शिता तुल्यता संबंधों के बिना प्रकारों तक सीमित है। उपयोगकर्ता-परिभाषित समतुल्य संबंधों के लिए संदर्भात्मक पारदर्शिता का विस्तार उदाहरण के लिए मार्टिन-लोफ़ पहचान प्रकार के साथ किया जा सकता है, लेकिन इसके लिए एग्डा, [[कॉक]] या [[इदरीस (प्रोग्रामिंग भाषा)|इदरीस]] जैसी निर्भरता से टाइप की गई प्रणाली की आवश्यकता होती है।


== [[अनिवार्य प्रोग्रामिंग]] के विपरीत ==
== [[अनिवार्य प्रोग्रामिंग]] के विपरीत ==

Revision as of 19:26, 16 July 2023

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

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

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

इतिहास

ऐसा प्रतीत होता है कि इस अवधारणा की उत्पत्ति ल्फ्रेड नॉर्थ व्हाइटहेड और बर्ट्रेंड रसेल की प्रिंसिपिया मैथमैटिका (1910-13) में हुई थी।[2] इसे विश्लेषणात्मक दर्शनशास्र में विलार्ड वान ऑरमैन क्विन द्वारा अपनाया गया था। वर्ड एंड ऑब्जेक्ट (1960) के §30 में क्वीन यह परिभाषा देती है:

नियंत्रण का एक तरीका φ संदर्भात्मक रूप से पारदर्शी है, यदि, जब भी एक एकल शब्द t की घटना किसी शब्द या वाक्य ψ(t) में विशुद्ध रूप से संदर्भित होती है, तो यह युक्त शब्द या वाक्य φ(ψ(t)) में भी पूरी तरह से संदर्भात्मक होती है।

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

उदाहरण और प्रति उदाहरण

यदि अभिव्यक्ति में शामिल सभी कार्य प्यूर फंक्शन हैं, तो अभिव्यक्ति संदर्भित रूप से पारदर्शी है।

किसी ऐसे फ़ंक्शन पर विचार करें जो किसी स्रोत से इनपुट वापस करता है। स्यूडोकोड में, इस फ़ंक्शन के लिए एक कॉल GetInput(Source) हो सकती है जहां Source एक विशेष डिस्क फ़ाइल, कीबोर्ड इत्यादि की पहचान कर सकता है। यहां तक कि Sourceके समान मानों के साथ भी, क्रमिक रिटर्न मान भिन्न होंगे। इसलिए, फ़ंक्शन GetInput() न तो नियतिवादी है और न ही संदर्भात्मक रूप से पारदर्शी है।

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

अंकगणितीय संक्रियाएं संदर्भात्मक रूप से पारदर्शी होती हैं: उदाहरण के लिए, 5 * 5 को 25 से बदला जा सकता है। वास्तव में, गणितीय अर्थ में सभी फ़ंक्शन संदर्भात्मक रूप से पारदर्शी हैं: sin(x) पारदर्शी है क्योंकि यह हमेशा प्रत्येक विशेष xके लिए समान परिणाम देगा।

पुनर्नियुक्तियाँ पारदर्शी नहीं हैं. उदाहरण के लिए, C एक्सप्रेशन x = x + 1, वेरिएबल xको निर्दिष्ट मान को बदल देता है। यह मानते हुए कि प्रारंभ मेंxका मान 10 है, अभिव्यक्ति के दो लगातार मूल्यांकन क्रमशः 11 और 12 प्राप्त करते हैं। स्पष्ट रूप से, x = x + 1 को 11 या 12 के साथ प्रतिस्थापित करने से एक अलग अर्थ वाला एक प्रोग्राम मिलता है, और इसलिए अभिव्यक्ति संदर्भात्मक रूप से पारदर्शी नहीं है . हालाँकि, किसी फ़ंक्शन को कॉल करना जैसे int plusone(int x) { return x + 1; } पारदर्शी है, क्योंकि यह इनपुट x को अंतर्निहित रूप से नहीं बदलेगा और इस प्रकार इसका कोई अनुषंगी प्रभाव नहीं होगा।

today() पारदर्शी नहीं है, जैसे कि आप इसका मूल्यांकन करते हैं और इसे इसके मूल्य से प्रतिस्थापित करते हैं (मान लीजिए, "Jan 1, 2001"), यदि आप इसे कल चलाएंगे तो आपको वैसा परिणाम नहीं मिलेगा जैसा आपको मिलेगा। ऐसा इसलिए है क्योंकि यह एक राज्य (कंप्यूटर विज्ञान) (तारीख) पर निर्भर करता है।

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

अनिवार्य प्रोग्रामिंग के विपरीत

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

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

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

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

एक और उदाहरण

उदाहरण के तौर पर, आइए दो फ़ंक्शन का उपयोग करें, एक जो संदर्भात्मक रूप से पारदर्शी है, और दूसरा जो संदर्भात्मक रूप से अपारदर्शी है:

int g = 0;

int rt(int x) {
  return x + 1;
}

int ro(int x) {
  g++;
  return x + g;
}

कार्यक्रम rt संदर्भात्मक रूप से पारदर्शी है, जिसका अर्थ है कि यदि x == y तब rt(x) == rt(y). उदाहरण के लिए, rt(6) = 7. हालाँकि हम ऐसी कोई बात नहीं कह सकते ro क्योंकि यह एक वैश्विक वैरिएबल का उपयोग करता है जिसे यह संशोधित करता है।

की संदर्भात्मक अस्पष्टता ro कार्यक्रमों के बारे में तर्क करना अधिक कठिन बना देता है। उदाहरण के लिए, मान लें कि हम निम्नलिखित कथन के बारे में तर्क करना चाहते हैं:

int i = ro(x) + ro(y) * (ro(x) - ro(x));

किसी को इस कथन को सरल बनाने का प्रलोभन हो सकता है:

int i = ro(x) + ro(y) * 0;
int i = ro(x) + 0;
int i = ro(x);

हालाँकि, यह काम नहीं करेगा ro क्योंकि प्रत्येक घटना ro(x) एक अलग मूल्य पर मूल्यांकन करता है। याद रखें कि का रिटर्न मान ro एक वैश्विक मूल्य पर आधारित है जिसे पारित नहीं किया जाता है और जिसे प्रत्येक कॉल पर संशोधित किया जाता है ro. इसका मतलब यह है कि गणितीय पहचान जैसे xx = 0 अब नहीं रुकना.

ऐसी गणितीय पहचानें संदर्भात्मक रूप से पारदर्शी कार्यों जैसे के लिए मान्य होंगी rt.

हालाँकि, कथन को सरल बनाने के लिए अधिक परिष्कृत विश्लेषण का उपयोग किया जा सकता है:

int tmp = g; int i = x + tmp + 1 + (y + tmp + 2) * (x + tmp + 3 - (x + tmp + 4)); g = g + 4;
int tmp = g; int i = x + tmp + 1 + (y + tmp + 2) * (x + tmp + 3 - x - tmp - 4)); g = g + 4;
int tmp = g; int i = x + tmp + 1 + (y + tmp + 2) * (-1); g = g + 4;
int tmp = g; int i = x + tmp + 1 - y - tmp - 2; g = g + 4;
int i = x - y - 1; g = g + 4;

इसमें अधिक कदम उठाने पड़ते हैं और कंपाइलर अनुकूलन के लिए अव्यवहार्य कोड में कुछ हद तक अंतर्दृष्टि की आवश्यकता होती है।

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

यह भी देखें

संदर्भ

  1. John C. Mitchell (2002). प्रोग्रामिंग भाषाओं में अवधारणाएँ. Cambridge University Press. p. 78.
  2. Alfred North Whitehead; Bertrand Russell (1927). गणितीय सिद्धांत. Vol. 1 (2nd ed.). Cambridge University Press. Here: p.665. According to Quine, the term originates from there.


बाहरी संबंध