संदर्भात्मक पारदर्शिता: Difference between revisions
No edit summary |
No edit summary |
||
(6 intermediate revisions by 4 users not shown) | |||
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 16: | Line 16: | ||
== उदाहरण और प्रति उदाहरण == | == उदाहरण और प्रति उदाहरण == | ||
यदि अभिव्यक्ति में | यदि अभिव्यक्ति में सम्मिलित सभी कार्य प्यूर फंक्शन हैं, तो अभिव्यक्ति संदर्भित रूप से पारदर्शी है। | ||
किसी ऐसे फ़ंक्शन पर विचार करें जो किसी स्रोत से इनपुट वापस करता है। स्यूडोकोड में, इस फ़ंक्शन के लिए | किसी ऐसे फ़ंक्शन पर विचार करें जो किसी स्रोत से इनपुट वापस करता है। स्यूडोकोड में, इस फ़ंक्शन के लिए कॉल <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>के लिए समान परिणाम देगा। | ||
Line 28: | Line 28: | ||
<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>x == y</code> तो <code>f(x) == f(y)</code>है। यह एक ऐसा गुण है जिसे अविभाज्य समरूपता के रूप में भी जाना जाता है। अनुषंगी प्रभाव वाली भाषाओं के लिए ऐसे गुणों को सामान्य रूप से लागू करने की आवश्यकता नहीं है। फिर भी, ऐसे दावों को तथाकथित निर्णयात्मक समानता तक सीमित करना महत्वपूर्ण है, जो कि सिस्टम द्वारा परीक्षण किए गए शब्दों की समानता है, जिसमें प्रकारों के लिए उपयोगकर्ता द्वारा परिभाषित समकक्षता सम्मिलित नहीं है। उदाहरण के लिए, यदि बी एफ (ए एक्स) और प्रकार ए ने समानता की धारणा को ओवरराइड कर दिया है, उदाहरण के लिए सभी पदों को समान बनाने पर,<code>x == y</code> होना संभव है और फिर भी <code>f(x) != f(y)</code> ज्ञात करना संभव है। ऐसा इसलिए है क्योंकि हास्केल जैसी प्रणालियाँ यह सत्यापित नहीं करती हैं कि उपयोगकर्ता-परिभाषित तुल्यता संबंधों वाले प्रकारों पर परिभाषित कार्यों को उस तुल्यता के संबंध में अच्छी तरह से परिभाषित किया जाना चाहिए। इस प्रकार संदर्भात्मक पारदर्शिता तुल्यता संबंधों के बिना प्रकारों तक सीमित है। उपयोगकर्ता-परिभाषित समतुल्य संबंधों के लिए संदर्भात्मक पारदर्शिता का विस्तार उदाहरण के लिए मार्टिन-लोफ़ पहचान प्रकार के साथ किया जा सकता है, लेकिन इसके लिए एग्डा, [[कॉक]] या [[इदरीस (प्रोग्रामिंग भाषा)|इदरीस]] जैसी निर्भरता से टाइप की गई प्रणाली की आवश्यकता होती है। | ||
== [[अनिवार्य प्रोग्रामिंग]] के विपरीत == | == [[अनिवार्य प्रोग्रामिंग]] के विपरीत == | ||
यदि किसी अभिव्यक्ति का उसके | यदि किसी अभिव्यक्ति का उसके मान के साथ प्रतिस्थापन केवल कार्यक्रम के निष्पादन में एक निश्चित बिंदु पर मान्य है, तो अभिव्यक्ति संदर्भित रूप से पारदर्शी नहीं है। इन अनुक्रम बिंदुओं की परिभाषा और क्रम अनिवार्य प्रोग्रामिंग की सैद्धांतिक नींव और एक अनिवार्य प्रोग्रामिंग भाषा के शब्दार्थ का हिस्सा हैं। | ||
हालाँकि, क्योंकि संदर्भात्मक रूप से पारदर्शी अभिव्यक्ति का मूल्यांकन किसी भी समय किया जा सकता है, इसलिए अनुक्रम बिंदुओं को परिभाषित करना आवश्यक नहीं | हालाँकि, क्योंकि संदर्भात्मक रूप से पारदर्शी अभिव्यक्ति का मूल्यांकन किसी भी समय किया जा सकता है, इसलिए अनुक्रम बिंदुओं या मूल्यांकन के आदेश की किसी प्रत्याभूति को परिभाषित करना आवश्यक नहीं है। इन विचारों के बिना की गई प्रोग्रामिंग को पूरी तरह कार्यात्मक प्रोग्रामिंग कहा जाता है। | ||
संदर्भात्मक रूप से पारदर्शी शैली में कोड लिखने का एक फायदा यह है कि एक बुद्धिमान कंपाइलर | संदर्भात्मक रूप से पारदर्शी शैली में कोड लिखने का एक फायदा यह है कि एक बुद्धिमान कंपाइलर दिए जाने पर, [[स्थैतिक कोड विश्लेषण]] आसान होता है और बेहतर कोड-सुधार परिवर्तन स्वचालित रूप से संभव होते हैं। उदाहरण के लिए, C में प्रोग्रामिंग करते समय, लूप के अंदर एक एक्सपेंसिव फ़ंक्शन में कॉल सम्मिलित करने के लिए एक प्रदर्शन पेनल्टी होगा, भले ही फ़ंक्शन कॉल को प्रोग्राम के परिणामों को बदले बिना लूप के बाहर ले जाया जा सके। प्रोग्रामर को संभवतः स्रोत कोड पठनीयता की कीमत पर, कॉल के मैन्युअल कोड मोशन को निष्पादित करने के लिए विवश किया जाएगा। हालाँकि, यदि कंपाइलर यह निर्धारित करने में सक्षम है कि फ़ंक्शन कॉल संदर्भात्मक रूप से पारदर्शी है, तो यह स्वचालित रूप से यह परिवर्तन कर सकता है। | ||
संदर्भात्मक पारदर्शिता को लागू करने वाली भाषाओं का प्राथमिक नुकसान यह है कि वे उन संचालन की अभिव्यक्ति | संदर्भात्मक पारदर्शिता को लागू करने वाली भाषाओं का प्राथमिक नुकसान यह है कि वे उन संचालन की अभिव्यक्ति करते हैं जो स्वाभाविक रूप से अनुक्रम-दर-चरण अनिवार्य प्रोग्रामिंग शैली में उपयुक्त होते हैं और अधिक अजीब और कम संक्षिप्त होते हैं। ऐसी भाषाएँ प्रायः भाषा की पूरी तरह कार्यात्मक गुणवत्ता को बनाए रखते हुए इन कार्यों को आसान बनाने के लिए निश्चित खंड व्याकरण और मोनैड तंत्र को सम्मिलित करती है। | ||
== एक और उदाहरण == | == एक और उदाहरण == | ||
उदाहरण के तौर पर, आइए दो | उदाहरण के तौर पर, आइए दो फ़ंक्शंस का उपयोग करें, एक जो संदर्भित रूप से पारदर्शी है, और दूसरा जो संदर्भात्मक रूप से अपारदर्शी है: | ||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
Line 54: | Line 54: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
फ़ंक्शन <code>rt</code> संदर्भित रूप से पारदर्शी है, जिसका अर्थ है कि यदि <code>x == y</code> तो <code>rt(x) == rt(y)</code> उदाहरण के लिए, <code>rt(6) = 7</code>. हालाँकि, हम <code>ro</code>के लिए ऐसी कोई बात नहीं कह सकते क्योंकि यह एक वैश्विक चर का उपयोग करता है जिसे यह संशोधित करता है। | |||
<code>ro</code> की संदर्भात्मक अपारदर्शिता कार्यक्रमों के बारे में तर्क करना अधिक कठिन बना देती है। उदाहरण के लिए, मान लें कि हम निम्नलिखित कथन पर तर्क करना चाहते हैं: | |||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
int i = ro(x) + ro(y) * (ro(x) - ro(x)); | int i = ro(x) + ro(y) * (ro(x) - ro(x)); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
कोई इस कथन को सरल बनाने के लिए प्रलोभित हो सकता है: | |||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
Line 68: | Line 68: | ||
int i = ro(x); | int i = ro(x); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
हालाँकि, यह | हालाँकि, यह<code>ro</code>के लिए काम नहीं करेगा क्योंकि <code>ro(x)</code> की प्रत्येक घटना का मूल्यांकन एक अलग मान पर होता है। याद रखें कि <code>ro</code> का रिटर्न मान एक वैश्विक मान पर आधारित होता है जिसे पास नहीं किया जाता है और जो <code>ro</code> पर प्रत्येक कॉल पर संशोधित हो जाता है। इसका मतलब यह है कि गणितीय पहचान जैसे कि {{Math|1=''x'' − ''x'' = 0}} अब मान्य नहीं है। | ||
ऐसी गणितीय पहचानें | ऐसी गणितीय पहचानें <code>rt</code>जैसे संदर्भात्मक रूप से पारदर्शी फंक्शन्स के लिए मान्य होंगी। | ||
हालाँकि, कथन को सरल बनाने के लिए | हालाँकि, अधिक परिष्कृत विश्लेषण का उपयोग कथन को सरल बनाने के लिए किया जा सकता है: | ||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
Line 81: | Line 81: | ||
int i = x - y - 1; g = g + 4; | int i = x - y - 1; g = g + 4; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
इसमें अधिक कदम उठाने पड़ते हैं और कंपाइलर अनुकूलन के लिए अव्यवहार्य कोड में | इसमें अधिक कदम उठाने पड़ते हैं और कंपाइलर अनुकूलन के लिए अव्यवहार्य कोड में अंतर्दृष्टि की आवश्यकता होती है। | ||
इसलिए, संदर्भात्मक पारदर्शिता हमें अपने कोड के बारे में तर्क करने की अनुमति देती है जिससे अधिक | इसलिए, संदर्भात्मक पारदर्शिता हमें अपने कोड के बारे में तर्क करने की अनुमति देती है जिससे अधिक सुदृढ़ प्रोग्राम बनेंगे, उन बगों को ढूंढने की संभावना होगी जिन्हें हम परीक्षण द्वारा ढूंढने की उम्मीद नहीं कर सकते हैं, और अनुकूलन के अवसरों को देखने की संभावना है। | ||
== यह भी देखें == | == यह भी देखें == | ||
* | *कंप्यूटर विज्ञान में निष्क्रियता | ||
* [[लिस्कोव प्रतिस्थापन सिद्धांत]] | * [[लिस्कोव प्रतिस्थापन सिद्धांत]] | ||
* [[नियम पुनः लिखें]] | * [[नियम पुनः लिखें]] | ||
Line 100: | Line 100: | ||
* https://stackoverflow.com/a/9859966/655289 by [http://www.cs.bham.ac.uk/~udr/ Prof. Uday Reddy] (University of Birmingham) | * https://stackoverflow.com/a/9859966/655289 by [http://www.cs.bham.ac.uk/~udr/ Prof. Uday Reddy] (University of Birmingham) | ||
* http://okmij.org/ftp/Computation/PrincipiaMathematica.txt | * http://okmij.org/ftp/Computation/PrincipiaMathematica.txt | ||
[[Category:Articles with hatnote templates targeting a nonexistent page]] | |||
[[Category: | |||
[[Category:Created On 08/07/2023]] | [[Category:Created On 08/07/2023]] | ||
[[Category:Lua-based templates]] | |||
[[Category:Machine Translated Page]] | |||
[[Category:Pages with script errors]] | |||
[[Category:Templates Vigyan Ready]] | |||
[[Category:Templates that add a tracking category]] | |||
[[Category:Templates that generate short descriptions]] | |||
[[Category:Templates using TemplateData]] | |||
[[Category:प्रोग्रामिंग भाषा सिद्धांत]] |
Latest revision as of 12:47, 29 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)
ज्ञात करना संभव है। ऐसा इसलिए है क्योंकि हास्केल जैसी प्रणालियाँ यह सत्यापित नहीं करती हैं कि उपयोगकर्ता-परिभाषित तुल्यता संबंधों वाले प्रकारों पर परिभाषित कार्यों को उस तुल्यता के संबंध में अच्छी तरह से परिभाषित किया जाना चाहिए। इस प्रकार संदर्भात्मक पारदर्शिता तुल्यता संबंधों के बिना प्रकारों तक सीमित है। उपयोगकर्ता-परिभाषित समतुल्य संबंधों के लिए संदर्भात्मक पारदर्शिता का विस्तार उदाहरण के लिए मार्टिन-लोफ़ पहचान प्रकार के साथ किया जा सकता है, लेकिन इसके लिए एग्डा, कॉक या इदरीस जैसी निर्भरता से टाइप की गई प्रणाली की आवश्यकता होती है।
अनिवार्य प्रोग्रामिंग के विपरीत
यदि किसी अभिव्यक्ति का उसके मान के साथ प्रतिस्थापन केवल कार्यक्रम के निष्पादन में एक निश्चित बिंदु पर मान्य है, तो अभिव्यक्ति संदर्भित रूप से पारदर्शी नहीं है। इन अनुक्रम बिंदुओं की परिभाषा और क्रम अनिवार्य प्रोग्रामिंग की सैद्धांतिक नींव और एक अनिवार्य प्रोग्रामिंग भाषा के शब्दार्थ का हिस्सा हैं।
हालाँकि, क्योंकि संदर्भात्मक रूप से पारदर्शी अभिव्यक्ति का मूल्यांकन किसी भी समय किया जा सकता है, इसलिए अनुक्रम बिंदुओं या मूल्यांकन के आदेश की किसी प्रत्याभूति को परिभाषित करना आवश्यक नहीं है। इन विचारों के बिना की गई प्रोग्रामिंग को पूरी तरह कार्यात्मक प्रोग्रामिंग कहा जाता है।
संदर्भात्मक रूप से पारदर्शी शैली में कोड लिखने का एक फायदा यह है कि एक बुद्धिमान कंपाइलर दिए जाने पर, स्थैतिक कोड विश्लेषण आसान होता है और बेहतर कोड-सुधार परिवर्तन स्वचालित रूप से संभव होते हैं। उदाहरण के लिए, C में प्रोग्रामिंग करते समय, लूप के अंदर एक एक्सपेंसिव फ़ंक्शन में कॉल सम्मिलित करने के लिए एक प्रदर्शन पेनल्टी होगा, भले ही फ़ंक्शन कॉल को प्रोग्राम के परिणामों को बदले बिना लूप के बाहर ले जाया जा सके। प्रोग्रामर को संभवतः स्रोत कोड पठनीयता की कीमत पर, कॉल के मैन्युअल कोड मोशन को निष्पादित करने के लिए विवश किया जाएगा। हालाँकि, यदि कंपाइलर यह निर्धारित करने में सक्षम है कि फ़ंक्शन कॉल संदर्भात्मक रूप से पारदर्शी है, तो यह स्वचालित रूप से यह परिवर्तन कर सकता है।
संदर्भात्मक पारदर्शिता को लागू करने वाली भाषाओं का प्राथमिक नुकसान यह है कि वे उन संचालन की अभिव्यक्ति करते हैं जो स्वाभाविक रूप से अनुक्रम-दर-चरण अनिवार्य प्रोग्रामिंग शैली में उपयुक्त होते हैं और अधिक अजीब और कम संक्षिप्त होते हैं। ऐसी भाषाएँ प्रायः भाषा की पूरी तरह कार्यात्मक गुणवत्ता को बनाए रखते हुए इन कार्यों को आसान बनाने के लिए निश्चित खंड व्याकरण और मोनैड तंत्र को सम्मिलित करती है।
एक और उदाहरण
उदाहरण के तौर पर, आइए दो फ़ंक्शंस का उपयोग करें, एक जो संदर्भित रूप से पारदर्शी है, और दूसरा जो संदर्भात्मक रूप से अपारदर्शी है:
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
पर प्रत्येक कॉल पर संशोधित हो जाता है। इसका मतलब यह है कि गणितीय पहचान जैसे कि x − x = 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;
इसमें अधिक कदम उठाने पड़ते हैं और कंपाइलर अनुकूलन के लिए अव्यवहार्य कोड में अंतर्दृष्टि की आवश्यकता होती है।
इसलिए, संदर्भात्मक पारदर्शिता हमें अपने कोड के बारे में तर्क करने की अनुमति देती है जिससे अधिक सुदृढ़ प्रोग्राम बनेंगे, उन बगों को ढूंढने की संभावना होगी जिन्हें हम परीक्षण द्वारा ढूंढने की उम्मीद नहीं कर सकते हैं, और अनुकूलन के अवसरों को देखने की संभावना है।
यह भी देखें
- कंप्यूटर विज्ञान में निष्क्रियता
- लिस्कोव प्रतिस्थापन सिद्धांत
- नियम पुनः लिखें
संदर्भ
- ↑ John C. Mitchell (2002). प्रोग्रामिंग भाषाओं में अवधारणाएँ. Cambridge University Press. p. 78.
- ↑ Alfred North Whitehead; Bertrand Russell (1927). गणितीय सिद्धांत. Vol. 1 (2nd ed.). Cambridge University Press. Here: p.665. According to Quine, the term originates from there.
- Søndergaard, Harald; Sestoft, Peter (1990). "Referential transparency, definiteness and unfoldability" (PDF). Acta Informatica. 27 (6): 505–517. doi:10.1007/bf00277387. S2CID 15806063.
- Davie, Antony (1992). An Introduction to Functional Programming Systems Using Haskell. New York: Cambridge University Press. p. 290. ISBN 0-521-27724-8.