संदर्भात्मक पारदर्शिता
This article includes a list of general references, but it lacks sufficient corresponding inline citations. (August 2016) (Learn how and when to remove this template message) |
कंप्यूटर विज्ञान में, संदर्भात्मक पारदर्शिता और संदर्भात्मक अस्पष्टता कंप्यूटर प्रोग्राम के कुछ हिस्सों के गुण हैं। एक अभिव्यक्ति (प्रोग्रामिंग) को संदर्भात्मक रूप से पारदर्शी कहा जाता है यदि इसे प्रोग्राम के व्यवहार को बदले बिना इसके संबंधित मूल्य (और इसके विपरीत) के साथ फिर से लिखा जा सकता है।[1] इसके लिए आवश्यक है कि अभिव्यक्ति शुद्ध कार्य हो - इसका मूल्य समान इनपुट के लिए समान होना चाहिए और इसके मूल्यांकन का कोई साइड इफेक्ट नहीं होना चाहिए (कंप्यूटर विज्ञान)। एक अभिव्यक्ति जो संदर्भात्मक रूप से पारदर्शी नहीं है उसे संदर्भात्मक रूप से अपारदर्शी कहा जाता है।
गणित में, फ़ंक्शन (गणित) का गठन करने वाली परिभाषा के अनुसार, सभी फ़ंक्शन एप्लिकेशन संदर्भात्मक रूप से पारदर्शी होते हैं। हालाँकि, प्रोग्रामिंग में हमेशा ऐसा नहीं होता है, जहाँ भ्रामक अर्थों से बचने के लिए प्रक्रिया (कंप्यूटर विज्ञान)|प्रक्रिया और विधि (कंप्यूटर विज्ञान)|विधि शब्दों का उपयोग किया जाता है। कार्यात्मक प्रोग्रामिंग की एक परिभाषित विशेषता यह है कि यह केवल संदर्भित रूप से पारदर्शी कार्यों की अनुमति देता है। अन्य प्रोग्रामिंग भाषाएँ चुनिंदा संदर्भात्मक पारदर्शिता की गारंटी देने के साधन प्रदान कर सकती हैं। कुछ कार्यात्मक प्रोग्रामिंग भाषाएँ सभी कार्यों के लिए संदर्भात्मक पारदर्शिता लागू करती हैं।
संदर्भात्मक पारदर्शिता का महत्व यह है कि यह प्रोग्रामर और संकलक को पुनर्लेखन प्रणाली के रूप में प्रोग्राम व्यवहार के बारे में तर्क करने की अनुमति देता है। यह शुद्धता (कंप्यूटर विज्ञान) को साबित करने, एक कलन विधि को सरल बनाने, कोड को बिना तोड़े उसे संशोधित करने में सहायता करने, या संस्मरण, सामान्य उपअभिव्यक्ति उन्मूलन, आलसी मूल्यांकन, या समानांतरीकरण के माध्यम से अनुकूलन (कंप्यूटर विज्ञान) कोड में मदद कर सकता है।
इतिहास
ऐसा प्रतीत होता है कि इस अवधारणा की उत्पत्ति अल्फ्रेड नॉर्थ व्हाइटहेड और बर्ट्रेंड रसेल की गणितीय सिद्धांत (1910-13) में हुई थी।[2] इसे विलार्ड वान ऑरमैन क्विन द्वारा विश्लेषणात्मक दर्शन में अपनाया गया था। वर्ड एंड ऑब्जेक्ट (1960) के §30 में क्विन यह परिभाषा देता है: <ब्लॉककोट> रोकथाम का एक तरीका φ संदर्भात्मक रूप से पारदर्शी है, यदि, जब भी एक एकल शब्द t की घटना किसी शब्द या वाक्य ψ(t) में पूरी तरह से संदर्भित होती है, तो यह युक्त शब्द या वाक्य φ(ψ(t)) में भी पूरी तरह से संदर्भित होती है। </ब्लॉककोट> यह शब्द अपने समकालीन कंप्यूटर विज्ञान के उपयोग में, प्रोग्रामिंग भाषाओं में चर (कंप्यूटर विज्ञान) की चर्चा में, क्रिस्टोफर स्ट्रेची के व्याख्यान नोट्स के मौलिक सेट प्रोग्रामिंग भाषाओं में मौलिक अवधारणाओं (1967) में दिखाई दिया। व्याख्यान नोट्स में ग्रंथ सूची में क्वीन के शब्द और वस्तु का संदर्भ दिया गया।
उदाहरण और प्रति उदाहरण
यदि अभिव्यक्ति में शामिल सभी फ़ंक्शन शुद्ध फ़ंक्शन हैं, तो अभिव्यक्ति संदर्भात्मक रूप से पारदर्शी है।
एक ऐसे फ़ंक्शन पर विचार करें जो किसी स्रोत से इनपुट लौटाता है। स्यूडोकोड में, इस फ़ंक्शन के लिए कॉल हो सकती है GetInput(Source)
कहाँ Source
किसी विशेष डिस्क फ़ाइल, कंप्यूटर कीबोर्ड आदि की पहचान कर सकता है, यहाँ तक कि समान मानों के साथ भी Source
, क्रमिक रिटर्न मान भिन्न होंगे। इसलिए, कार्य करें GetInput()
न तो नियतिवादी है और न ही संदर्भात्मक रूप से पारदर्शी है।
एक अधिक सूक्ष्म उदाहरण एक फ़ंक्शन का है जिसमें एक मुक्त चर होता है, यानी, कुछ इनपुट पर निर्भर करता है जो स्पष्ट रूप से पैरामीटर के रूप में पारित नहीं होता है। इसके बाद इसे गैर-स्थानीय वैरिएबल के नाम बंधन नियमों के अनुसार हल किया जाता है, जैसे कि वैश्विक वैरिएबल, वर्तमान निष्पादन वातावरण में एक वैरिएबल (देर से बंधन के लिए), या क्लोजर (कंप्यूटर विज्ञान) में एक वैरिएबल (स्थैतिक बाइंडिंग के लिए) . चूँकि इस वेरिएबल को पैरामीटर के रूप में पारित मानों को बदले बिना बदला जा सकता है, फ़ंक्शन के बाद के कॉल के परिणाम भिन्न हो सकते हैं, भले ही पैरामीटर समान हों। हालाँकि, शुद्ध कार्यात्मक प्रोग्रामिंग में, विनाशकारी असाइनमेंट की अनुमति नहीं है, और इस प्रकार यदि मुक्त चर स्थिर रूप से एक मूल्य से बंधा हुआ है, तो फ़ंक्शन अभी भी संदर्भात्मक रूप से पारदर्शी है, क्योंकि स्थैतिक बंधन के कारण न तो गैर-स्थानीय चर और न ही इसका मूल्य बदल सकता है। और अपरिवर्तनीय वस्तु, क्रमशः।
अंकगणितीय परिचालन संदर्भात्मक रूप से पारदर्शी हैं: 5 * 5
द्वारा प्रतिस्थापित किया जा सकता है 25
, उदाहरण के लिए। वास्तव में, गणितीय अर्थ में सभी कार्य संदर्भात्मक रूप से पारदर्शी हैं: sin(x)
पारदर्शी है, क्योंकि यह हमेशा प्रत्येक विशेष के लिए समान परिणाम देगा x
.
पुनर्नियुक्ति पारदर्शी नहीं हैं. उदाहरण के लिए, सी (प्रोग्रामिंग भाषा) अभिव्यक्ति 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)
. यह एक ऐसी संपत्ति है जिसे अविवेकी की पहचान के रूप में भी जाना जाता है। साइड-इफेक्ट वाली भाषाओं के लिए ऐसे गुणों को सामान्य रूप से लागू करने की आवश्यकता नहीं है। फिर भी, ऐसे दावों को तथाकथित निर्णयात्मक समानता तक सीमित करना महत्वपूर्ण है, जो कि सिस्टम द्वारा परीक्षण किए गए शब्दों की समानता है, जिसमें प्रकारों के लिए उपयोगकर्ता द्वारा परिभाषित समकक्षता शामिल नहीं है। उदाहरण के लिए, यदि B f(A x)
और प्रकार A
समानता की धारणा को खत्म कर दिया है, उदा. सभी पदों को समान बनाने पर यह संभव है 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
. इसका मतलब यह है कि गणितीय पहचान जैसे 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.