जैसा कि मैं प्रतिस्थापन मॉडल (संदर्भात्मक पारदर्शिता (आरटी)) के साथ मोटे तौर पर समझता हूं, आप किसी फ़ंक्शन को उसके सरल भागों में डी-कंपोज कर सकते हैं। यदि अभिव्यक्ति आरटी है, तो आप अभिव्यक्ति को डी-कंपोज कर सकते हैं और हमेशा एक ही परिणाम प्राप्त कर सकते हैं।
हां, अंतर्ज्ञान काफी सही है। यहाँ अधिक सटीक होने के लिए कुछ संकेत दिए गए हैं:
जैसा आपने कहा, किसी भी आरटी अभिव्यक्ति का single
"परिणाम" होना चाहिए । यही है, factorial(5)
कार्यक्रम में एक अभिव्यक्ति दी गई है , इसे हमेशा एक ही "परिणाम" प्राप्त करना चाहिए। इसलिए, यदि एक निश्चित factorial(5)
कार्यक्रम में है और इसकी पैदावार 120 है, तो इसे हमेशा 120 की पैदावार करनी चाहिए, जिसकी परवाह किए बिना "चरण क्रम" का विस्तार / गणना की जाती है - समय की परवाह किए बिना ।
उदाहरण: factorial
कार्य।
def factorial(n):
if n == 1:
return 1
return n * factorial(n - 1)
इस स्पष्टीकरण के साथ कुछ विचार हैं।
सबसे पहले, अलग-अलग मूल्यांकन मॉडल (आवेदक बनाम सामान्य क्रम देखें) को ध्यान में रखते हुए एक ही आरटी अभिव्यक्ति के लिए अलग-अलग "परिणाम" प्राप्त कर सकते हैं।
def first(y, z):
return y
def second(x):
return second(x)
first(2, second(3)) # result depends on eval. model
ऊपर दिए गए कोड में, first
और second
संदर्भित रूप से पारदर्शी हैं, और फिर भी, अंत में अभिव्यक्ति अलग-अलग "परिणाम" देती है यदि सामान्य क्रम और आवेदन क्रम के तहत मूल्यांकन किया जाता है (बाद के तहत, अभिव्यक्ति रुक नहीं जाती है)।
.... जो उद्धरणों में "परिणाम" का उपयोग करता है। चूंकि इसे रोकने के लिए अभिव्यक्ति की आवश्यकता नहीं है, इसलिए यह मान उत्पन्न नहीं कर सकता है। तो "परिणाम" का उपयोग धुंधला की तरह है। कोई कह सकता है कि एक RT अभिव्यक्ति हमेशा computations
एक मूल्यांकन मॉडल के तहत एक ही पैदावार देता है ।
तीसरा, foo(50)
अलग-अलग स्थानों में कार्यक्रम में दो को अलग-अलग अभिव्यक्तियों के रूप में देखना आवश्यक हो सकता है - हर एक अपने स्वयं के परिणाम प्राप्त कर सकता है जो एक दूसरे से भिन्न हो सकते हैं। उदाहरण के लिए, यदि भाषा गतिशील गुंजाइश की अनुमति देती है, तो दोनों अभिव्यक्तियां, हालांकि शाब्दिक रूप से समान हैं, अलग-अलग हैं। पर्ल में:
sub foo {
my $x = shift;
return $x + $y; # y is dynamic scope var
}
sub a {
local $y = 10;
return &foo(50); # expanded to 60
}
sub b {
local $y = 20;
return &foo(50); # expanded to 70
}
डायनेमिक स्कोप गुमराह करता है क्योंकि यह आसान लगता x
है कि किसी के लिए यह एकमात्र इनपुट है foo
, जब वास्तव में, यह है x
और y
। अंतर देखने का एक तरीका यह है कि प्रोग्राम को डायनेमिक स्कोप के बिना एक समतुल्य में बदल दिया जाए - यानी, स्पष्ट रूप से मापदंडों को पास करना, इसलिए परिभाषित करने के बजाय foo(x)
, हम कॉलर्स में स्पष्ट रूप से परिभाषित foo(x, y)
और पास y
करते हैं।
मुद्दा यह है, हम हमेशा एक function
मानसिकता के अंतर्गत होते हैं : एक अभिव्यक्ति के लिए एक निश्चित इनपुट दिया जाता है, हमें एक "परिणाम" दिया जाता है। यदि हम एक ही इनपुट देते हैं, तो हमें हमेशा उसी "परिणाम" की अपेक्षा करनी चाहिए।
अब, निम्नलिखित कोड के बारे में क्या?
def foo():
global y
y = y + 1
return y
y = 10
foo() # yields 11
foo() # yields 12
foo
प्रक्रिया आर टी टूट जाता है क्योंकि वहाँ redefinitions हैं। यही है, हमने y
एक बिंदु में परिभाषित किया, और बाद में उसी को फिर से परिभाषित किया y
। उपरोक्त पर्ल उदाहरण में, y
एस अलग-अलग बाइंडिंग हैं, हालांकि वे एक ही अक्षर का नाम "y" साझा करते हैं। यहाँ y
वास्तव में वही हैं। इसलिए हम कहते हैं (पुनः) असाइनमेंट एक मेटा ऑपरेशन है: आप वास्तव में अपने प्रोग्राम की परिभाषा बदल रहे हैं।
मोटे तौर पर, लोग आमतौर पर अंतर को निम्नानुसार दर्शाते हैं: साइड-इफेक्ट फ्री सेटिंग में, आपके पास मैपिंग है input -> output
। एक "अनिवार्य" सेटिंग में, आप input -> ouput
एक के संदर्भ में state
उस समय के माध्यम से बदल सकते हैं।
अब, अपने संबंधित मूल्यों के लिए केवल भावों को प्रतिस्थापित करने के बजाय, state
प्रत्येक को प्रत्येक ऑपरेशन में परिवर्तनों को भी लागू करना पड़ता है जिसके लिए इसकी आवश्यकता होती है (और निश्चित रूप से, अभिव्यक्तियाँ state
गणना करने के लिए उसी से परामर्श कर सकती हैं )।
इसलिए, यदि साइड-इफ़ेक्ट फ़्री प्रोग्राम में, हम सभी को एक्सप्रेशन की गणना करने के लिए जानना आवश्यक है, तो यह एक व्यक्तिगत इनपुट है, अनिवार्य प्रोग्राम में, हमें प्रत्येक कम्प्यूटेशनल स्टेप के लिए इनपुट और पूरे स्टेट्स को जानना होगा। रीज़निंग एक बड़ा झटका भुगतने वाला पहला है (अब, एक समस्याग्रस्त प्रक्रिया को डीबग करने के लिए, आपको इनपुट और कोर डंप की आवश्यकता है)। कुछ तरकीबों को अव्यवहारिक रूप दिया जाता है, जैसे संस्मरण। लेकिन साथ ही, संगामिति और समानता अधिक चुनौतीपूर्ण हो जाती है।
RT
आपको उपयोग करने से रोकता हैsubstitution model.
बड़ी समस्या जिसका उपयोग नहीं कर पा रहाsubstitution model
है क्या वह प्रोग्राम के बारे में तर्क करने के लिए उपयोग करने की शक्ति है?