आज () एक अशुद्ध कार्य का एक उदाहरण क्यों है?


38

ऐसा लगता है, जब "शुद्ध कार्यों" के बारे में इस विकिपीडिया लेख को पढ़ते हुए , वे Today()एक अशुद्ध कार्य के उदाहरण के रूप में सूचीबद्ध होते हैं, लेकिन यह मुझे बहुत शुद्ध लगता है। क्या इसलिए कि कोई औपचारिक इनपुट तर्क नहीं है? दिन का वास्तविक समय "फ़ंक्शन के इनपुट" के रूप में क्यों नहीं माना जाता है अगर आपने इसे एक ही इनपुट दिया है, यानी today()एक ही समय में दो बार निष्पादित किया गया है, या इसे फिर से निष्पादित करने के लिए समय में वापस यात्रा की है (शायद एक काल्पनिक: )), आउटपुट एक ही समय होगा। Today()कभी आपको रैंडम नंबर नहीं देता है। यह हमेशा आपको दिन का समय देता है।

विकिपीडिया लेख कहते हैं लेकिन यह है कि के "अलग अलग समय यह अलग परिणाम मिलेंगे" अलग के लिए कह रही है की तरह x sin(x)आप विभिन्न अनुपात दे देंगे। और sin(x)एक शुद्ध कार्य का उनका उदाहरण है।


8
यदि आप दिन के समय में गुजर गए, तो कार्य क्या करेगा?
जेबी किंग

1
मुझे उम्मीद है कि यह आपको दिन का समय देगा। (सबसे उपयोगी फ़ंक्शन नहीं)। लेकिन इसका कोई तर्क नहीं है, जो मुझे लगता है कि उत्तर की जड़ है।
ब्रैड

3
क्या आप इसके आउटपुट (आपके द्वारा प्रदत्त इनपुट मापदंडों के आधार पर) की भविष्यवाणी कर सकते हैं?
डेनियल बी

1
@ डैनियलबी अनुपस्थित / अशक्त इनपुट पैरामीटर के लिए कोई भविष्य कहनेवाला शक्ति नहीं है। केवल एक चीज जो मैं कर सकता हूं वह है मेरी कलाई घड़ी (jk my cell phone)।
ब्रैड

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

जवाबों:


103

क्या इसलिए कि कोई औपचारिक इनपुट तर्क नहीं है?

इसका कारण यह है कि आउटपुट उस चीज पर निर्भर करता है जो इनपुट नहीं है, अर्थात वर्तमान समय।

दिन के वास्तविक समय को "फ़ंक्शन के इनपुट" के रूप में क्यों नहीं माना जाता है

क्योंकि आपने इसे एक पैरामीटर के रूप में पारित नहीं किया है। यदि आपने इसे एक पैरामीटर के रूप में पारित किया है, तो फ़ंक्शन तिथियों पर एक पहचान समारोह बन जाएगा, जो बहुत बेकार है। किसी Today()फ़ंक्शन का संपूर्ण बिंदु कुछ ऐसा आउटपुट करना है जो बाहरी और लगातार बदलते मूल्य (समय) पर निर्भर करता है।

शुद्ध कार्यों का लाभ यह है कि उनका व्यवहार पूरी तरह से प्रतिलिपि प्रस्तुत करने योग्य और नियतात्मक है, जिससे औपचारिक प्रमाण और कठिन गारंटी प्राप्त करना आसान हो जाता है। वे हमेशा एक ही काम करते हैं। Today()बहुत ज्यादा विपरीत है: यह हमेशा (समय की गंभीरता के लिए अनुमति देता है) कुछ अलग करता है।


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

1
@ ब्रैड कुछ हद तक एक ग्रे क्षेत्र है - इसमें एक अंतर्निहित वास्तविक तर्क है - सरणी या सूची। एक अपरिवर्तनीय सूची और हर बार एक ही तर्क को देखते हुए यह हमेशा एक ही मूल्य लौटाएगा।
मैक्स

34
"वास्तविकता का समय एक इनपुट की तरह है" - हाँ; वास्तव में, वैश्विक राज्य सभी कार्यों के लिए निहित है (यानी 'एक प्रकार का इनपुट'), लेकिन अगर वे अपने परिणाम के लिए इस पर निर्भर हैं तो वे अशुद्ध हैं!
आकाशवाणी

4
count()अधिकांश प्रोग्रामिंग भाषाओं पर @ ब्रैड निश्चित रूप से शुद्ध है। इसका एक स्पष्ट इनपुट मूल्य है: वह संग्रह जिसकी गिनती आप चाहते हैं। एक वाक्य रचना से भ्रमित मत हो जैसे myCollection.count(); इसके लिए सिर्फ चीनी है count(myCollection)
एंड्रेस एफ।

हमेशा की तरह शानदार जवाब, लेकिन यह स्पष्ट रूप से अपरिवर्तनीय मुक्त चर को कवर नहीं करता है। वे फ़ंक्शन के लिए इनपुट नहीं हैं - पैरामीटर के रूप में पारित नहीं हुए - लेकिन फ़ंक्शन उन पर निर्भर करता है, भले ही यह अभी भी पारदर्शी हो।

24

sin(x)हमेशा उतना ही मूल्य लौटाएगा, जब तक xकि एक जैसा रहता है। Today()समय के साथ विभिन्न परिणाम लौटा सकता है क्योंकि यह आपके नियंत्रण के बाहर के मूल्यों पर निर्भर करता है । उदाहरण के लिए, यदि आपके प्रोग्राम के नियंत्रण से परे कोई चीज सिस्टम के आंतरिक $current_datetime को बदल देती है, जबकि आपका प्रोग्राम चल रहा है, Today()तो अचानक अलग परिणाम मिलेंगे।


"हमेशा एक अलग मूल्य लौटाएगा" थोड़ा सा है ... अशुद्ध शब्द। विकिपीडिया कहता है "सप्ताह का वर्तमान दिन लौटाता है" जिसका अर्थ है कि सोमवार को प्राप्त मूल्य अलग नहीं होंगे
gnat

7
@gnat: सच है, जब तक कि आपके प्रोग्राम के लिए कुछ बाहरी आपके कंप्यूटर के आंतरिक कैलेंडर को बदल नहीं देता है ताकि यह अचानक लगे कि यह गुरुवार था। फिर कॉलिंग Today()सोमवार को "गुरुवार" लौटेगी।
FrustratedWithFormsDesigner

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

3
@ डायलेन: हाँ, यह भोले डेटाबेस स्क्रिप्ट लेखकों का प्रतिबंध है! : पी "लेकिन कैसे यह 300 रिकॉर्ड को याद कर सकता है? जब मैंने कल सुबह इसका परीक्षण किया तो स्क्रिप्ट ठीक काम कर रही थी!"
FrustratedWithFormsDesigner

@delnan यह सुनिश्चित करने के लिए है। मैं केवल ने कहा कि का उपयोग करते हुए हमेशा प्रारंभिक शब्दों में (करने के लिए वर्तमान संस्करण जवाब में सही कर सकता है ) कुछ हद तक अनिश्चित था
कुटकी

13

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

एक शुद्ध कार्य होगा int Add(int a, int b) {return a + b;}। फ़ंक्शन पूरी तरह से काम करता है जो इसे दिया गया है, और कोई अन्य बाहरी राज्य डेटा का उपयोग नहीं करता है। इसका स्वाभाविक परिणाम यह है कि आप Add(2,2)समय के अंत तक अब से 4 प्राप्त कर सकते हैं। इसके अलावा, क्योंकि फ़ंक्शन किसी भी बाहरी स्थिति को नहीं बदलता है (इसका कोई "साइड इफेक्ट्स" नहीं है), जोड़ें () आईएनजी 2 और 2 अब से तब तक जब तक सिस्टम में कुछ और नहीं बदलेगा, जब तक आप तब तक फ़ंक्शन के परिणाम को एक चर पर असाइन करें या अन्यथा अद्यतन स्थिति के लिए मान का उपयोग करें (जो कि फ़ंक्शन द्वारा स्वयं निष्पादित कोई ऑपरेशन नहीं है)। वस्तुतः सभी शास्त्रीय गणितीय कार्य शुद्ध कार्य हैं और इन्हें इस तरह लागू किया जा सकता है।

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

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

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


8

यह स्पष्ट प्रतीत होता है कि यह कार्य उस पृष्ठ के आरंभ में दी गई शुद्धता की पहली परीक्षा में विफल रहता है:

  1. फ़ंक्शन हमेशा एक ही परिणाम मान का मूल्यांकन करता है जिसे समान तर्क मान दिया गया है। फ़ंक्शन परिणाम मान किसी भी छिपी जानकारी या स्थिति पर निर्भर नहीं हो सकता है जो प्रोग्राम निष्पादन आय या प्रोग्राम के विभिन्न निष्पादन के बीच बदल सकता है, और न ही यह I / O उपकरणों से किसी भी बाहरी इनपुट पर निर्भर हो सकता है।

ध्यान दें कि चूंकि यह कोई तर्क नहीं लेता है, इसलिए तर्क मानों का केवल एक संभावित सेट है - खाली सेट। और यह फ़ंक्शन समान 'तर्क मान' के लिए अलग-अलग परिणाम दे सकता है और वापस कर सकता है ।

इसके अलावा, फ़ंक्शन परिणाम मान "छिपी ... स्थिति पर निर्भर करता है जो प्रोग्राम निष्पादन आय के रूप में बदल सकता है"। तो एक और विफलता।


@ JörgWMittag मुझे यकीन नहीं है कि मैं दावा करता हूं कि बिना किसी तर्क के एक फ़ंक्शन मान वापस नहीं कर सकता।
आकाशवाणी

दिमाग़ का दही। मैंने पढ़ा " वापसी मूल्यों का केवल एक ही संभव सेट है "।
जोर्ग डब्ल्यू मित्तग

8

() => 1एक शुद्ध कार्य होगा, क्योंकि यह हमेशा रिटर्न करता है 1. Today()"सोमवार" या "मंगलवार" या लगभग किसी अन्य मूल्य पर वापस आ सकता है।

यह सोचने का एक और तरीका शुद्ध कार्य है जो राज्य पर निर्भर नहीं करता है। दुनिया आमतौर पर राज्य माना जाता है। आज का दिन क्या है, यह जानने के लिए आपको वास्तविकता की स्थिति को जानना होगा।

हालाँकि आपको यह जानने के लिए दुनिया की स्थिति के बारे में कुछ विशेष जानने की आवश्यकता नहीं sin(x)है। और कभी भी sin(x)दिए गए के लिए कॉल करने xपर समान मूल्य वापस आ जाएगा।


विकिपीडिया कहता है "सप्ताह का वर्तमान दिन लौटाता है", जिसका अर्थ है कि यह सोमवार, मंगलवार आदि पर लौट सकता है, लेकिन "1/23/2013" या "1/24/2013" नहीं
gnat

7
@gnat: अपडेट किया गया, लेकिन अंतर वास्तव में भौतिक नहीं था।
ग्वेंटे

2

Date(timestamp)एक शुद्ध कार्य होगा। अपनी बेमियादी वजह से। और क्योंकि कोई साइड-इफेक्ट नहीं होगा।

Today()जब आप इसे कहते हैं, तो इसके परिणाम भिन्न हो सकते हैं । वही इसे अशुद्ध बनाता है। यह बेकार नहीं है। हालांकि इसका कोई साइड-इफेक्ट नहीं है, लेकिन यह इसे शुद्ध नहीं बनाता है।


2

यहाँ थोड़ा छद्म कोड है जो मुझे लगता है कि शुद्ध कार्यों पर चर्चा करते समय

newValue = Function();
while(true)
{
   oldValue = newValue;
   newValue = Function();
   assert( newValue == oldValue );
}

यदि वह अनिश्चित काल तक चलता है और कभी जोर नहीं दे सकता है, तो यह एक शुद्ध कार्य है। और तो और, अगर आपके पास कोई ऐसा फंक्शन है जो args का उपयोग करता है, तो थोड़ा संशोधन करें ...।

oldValue = Function( importantVariableToYourApp );
newValue = Function( importantVariableToYourApp );
assert( newValue == oldValue );

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


2

सबसे पहले, बिना तर्क (या अनुक्रमों के बिना एक सरणी या बिना चाबी के एक नक्शा) के बिना फ़ंक्शन के रूप में ऐसी कोई चीज नहीं है। किसी एक या एक से अधिक तर्क मानों को दूसरे मान पर मैप करना किसी फ़ंक्शन की परिभाषित विशेषता है।

इसलिए, todayया तो कोई फ़ंक्शन नहीं है, इसलिए कोई शुद्ध फ़ंक्शन नहीं है। या हम वाक्य रचना की व्याख्या कर सकते हैं

today()

थोड़ा इतना कि इसका मतलब है

today   ()      -- today, applied to the value ()

हास्केल में, उदाहरण के लिए, यह मान्य होगा:

data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving Show
today :: () -> Day
today () = ....?
main = print (today())

क्योंकि एकल मान () के साथ एक प्रकार () है।

प्रश्न केवल todayयह है कि सप्ताह के दिन की गणना कैसे की जा सकती है , अगर यह केवल () है? यह सीधे सिस्टम टाइमर को पढ़े बिना, सीधे या सहायक अशुद्ध कार्यों के माध्यम से संभव नहीं है।

सिस्टम टाइमर वैश्विक स्थिति के लिए एक उत्कृष्ट उदाहरण है।


1

इसके साथ समस्या today()यह है कि यह एक अलग परिणाम दे सकता है अगर एक फ़ंक्शन में दो या अधिक बार कहा जाता है।

यहाँ एक कोड उदाहरण है, जो बग का परिचय दे सकता है।

function doSomething(when)
{
     if(today() == when)
     {
           // open a resource or create a temp file.....
     }

     // do some other work

     if(today() == when)
     {
           // close the resource or delete temp file.....
     }
}

यह उपरोक्त उदाहरण में संभव है। कि दूसरा ifकथन निष्पादित नहीं करेगा। भले ही पहले वाले ने किया। किसी संसाधन को खराब स्थिति में छोड़ना।


1

एक शुद्ध कार्य करने के लिए, समान पैरामीटर प्रदान करना हर बार एक ही परिणाम देना चाहिए।

जितनी बार हम कॉल Today()करते हैं, हम इसे एक ही पैरामीटर (कोई नहीं) प्रदान कर रहे हैं, और अभी तक जरूरी नहीं कि एक ही परिणाम (सोमवार, मंगलवार, आदि) प्राप्त कर रहे हैं।


4
ऐसा लगता है कि केवल दो साल पहले पोस्ट किए गए एक शीर्ष जवाब में केवल दोहराए गए बिंदु और समझाया गया था। इस तरह की सामग्री के साथ मुश्किल से दो साल पुराने सवाल
gnat

1
मैं बहुत परिचित नहीं हूं कि स्टैकएक्सचेंज कैसे काम करता है, लेकिन मुझे लगा कि चूंकि यह शीर्ष सवालों में था कि यह पहले ही टकरा गया था। जहाँ तक एक रिपीट पॉइंट बनने की बात है, मुझे याद है कि मेटा पर पढ़ना यह है कि यह कई तरह के उत्तर देने में मददगार हो सकता है। मुझे ऐसा लगता है कि मेरा आत्महत्या और संभावित रूप से सहायक है।
ज़ांटियर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.