2012-02-23 16 views
19

कार्यात्मक प्रोग्रामिंग "राज्य और परिवर्तनीय डेटा से बचाता है"।कार्यात्मक प्रोग्रामिंग प्रतिमान का उल्लंघन बंद कर रहे हैं?

क्लोजर अपने लेक्सिकल वातावरण को बाध्य करके राज्य छुपाते हैं और इस प्रकार उनके मुक्त चर पर बंद हो जाते हैं।

अगर यह बंद करने का समर्थन करता है तो हास्केल पूरी तरह से कार्यात्मक कैसे होता है? क्या वे संदर्भित पारदर्शिता तोड़ते हैं?

+14

जब चर वैधानिक पारदर्शिता तोड़ते हैं? गणित के रूप में यह पारदर्शी रूप से पारदर्शी है, फिर भी उन अजीब गणितज्ञ पूरे दिन चर लगते हैं। – delnan

+5

कार्यान्वयन में राज्य शामिल हो सकता है, लेकिन अर्थात् बोलने पर कोई उत्परिवर्तन नहीं चल रहा है। –

+3

हास्केल फ़ंक्शन में नि: शुल्क चर या तो अन्य कार्य, निरंतर आवेदक रूप या पहले से लागू तर्क (आंशिक अनुप्रयोग) हो सकते हैं, जिनमें से कुछ भी संदर्भित पारदर्शिता को तोड़ता है। – Vitus

उत्तर

21

हास्केल में, क्लोजर में उसी तरह से भिन्न चर होते हैं जैसे गणित में आप f x = x^2 लिख सकते हैं - यह राज्य को म्यूट नहीं करता है।

मैं कहूंगा कि हास्केल उत्परिवर्तनीय राज्य से बचाता है।

16

क्लोजर उल्लंघन नहीं हैं क्योंकि हास्केल में सभी बाइंडिंग अपरिवर्तनीय हैं। वास्तव में क्या बंद होने का मतलब यह है कि मुक्त चर के साथ एक लैम्ब्डा एक अद्वितीय कार्य को इंगित नहीं करता है; यह अलग-अलग कार्यों को इंगित करेगा जो बाइंडिंग के आधार पर प्रभावी रूप से प्रभावी होते हैं जब प्रत्येक बार इसका मूल्यांकन किया जाता है। उदा .:

makeClosure :: Num a => a -> a -> a 
makeClosure x = \y -> x+y 

अभिव्यक्ति makeClosure 5makeClosure 6 तुलना में एक अलग समारोह का मूल्यांकन; और अधिक महत्वपूर्ण बात यह है कि कार्यक्रम के विभिन्न हिस्सों में makeClosure 5 की दो घटनाएं उसी फ़ंक्शन पर मूल्यांकन करती हैं, जैसा कि makeClosure (2+3) या इसी प्रकार है; यानी, हमारे पास रेफरेंसियल पारदर्शिता है (उनके बराबर के साथ अभिव्यक्तियों को प्रतिस्थापित करना एक प्रोग्राम के अर्थ को संरक्षित करता है)।

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

12

नहीं, बंद होने ठीक हैं और हास्केल में समस्याएं नहीं आती हैं क्योंकि बंद होने पर मूल्य पर बंद हो जाता है। अन्य भाषाओं में बंद होने के पीछे राज्य को छिपाने का कारण यह है कि आप संदर्भ पर बंद कर देते हैं। आप जानते हैं, जावास्क्रिप्ट में:

var x = 1; 
var f = function(y) { return y + x; } 
f(2) // => 3 
x = 2; 
f(2) // => 4 

आप वास्तव में हास्केल में IORef रों का उपयोग करके इस मॉडल कर सकते हैं:

main = do 
    x <- newIORef 1 
    let f y = do x' <- readIORef x 
       return (y + x') 
    r1 <- f 2 
    writeIORef x 2 
    r2 <- f 2 

यह ठीक है क्योंकि समारोह fInt -> IO Int बजाय Int -> Int टाइप किया है। दूसरे शब्दों में, f एक ही क्रिया के लिए बाध्य है, लेकिन जब निष्पादित किया गया था तो वही क्रिया प्रत्येक बार अलग-अलग परिणाम लौटा सकती है।

+1

अच्छी नौकरी। मैंने प्रायः बंद करने के बारे में टिप्पणियां देखी हैं जैसे "कार्यात्मक प्रोग्रामिंग का मुख्य" जावास्क्रिप्ट बंद करने की चर्चा में स्पष्ट रूप से उल्लेख किया गया है। विडंबना यह है कि यदि आप जेएस क्लोजर से सावधान नहीं हैं तो आप विभिन्न राज्य से संबंधित प्रभाव/बग प्राप्त कर सकते हैं क्योंकि वे किसी मूल्य के बजाय संदर्भ पर हैं। एक समाधान है कि क्लोजर संदर्भ का उपयोग करते हुए * पैरामीटर * के बजाय मान को स्पष्ट रूप से पास करना है (यानी ऊपर और आपके फ़ंक्शन एफ के पैरामीटर के रूप में दोनों एक्स और वाई को गुजरना)। तो यह वास्तव में अधिक 'कार्यात्मक' दृष्टिकोण है, है ना? –

2

मेरे कामकाजी आदमी की "कार्यात्मक प्रोग्रामिंग" की परिभाषा यह है कि यदि आप एक ही चीज़ डालते हैं, तो आप हमेशा वही चीज़ प्राप्त करते हैं।

क्लोजर हास्केल में इस परिभाषा का उल्लंघन नहीं करते हैं (कोशिश करें और बंद होने के साथ आओ :)), इसलिए बंद एफपी प्रतिमान का उल्लंघन नहीं करते हैं।

संबंधित मुद्दे