5

मैं ओडर्स्की, चम्मच और वेनेर्स द्वारा स्कैला 2 संस्करण में प्रोग्रामिंग के माध्यम से जा रहा हूं, और इस उदाहरण ने मुझे एक लूप के लिए फेंक दिया क्योंकि ऐसा लगता है कि मैंने जो काम किया वह कार्यात्मक प्रोग्रामिंग के बारे में सच था और अचल स्थिति। उदाहरण में (और पहले च। 18 में पुस्तक में), लेखकों का दावा है कि किसी ऑब्जेक्ट पर ऑपरेशन अभी भी "पूरी तरह कार्यात्मक" हो सकता है, भले ही वे ऑपरेशन आंतरिक रूप से ऑब्जेक्ट की स्थिति को पार कर सकें। उदाहरण, जो पी 442 पर है, च। 19, यह है:स्कैला में प्रोग्रामिंग से कार्यात्मक कतार

class Queue[+T] private (
    private[this] var leading: List[T], 
    private[this] var trailing: List[T] 
) { 

    private def mirror() = 
    if (leading.isEmpty) { 
     while (!trailing.isEmpty) { 
     leading = trailing.head :: leading 
     trailing = trailing.tail 
     } 
    } 

    def head: T = { 
    mirror() 
    leading.head 
    } 

    def tail: Queue[T] = { 
    mirror() 
    new Queue(leading.tail, trailing) 
    } 

    def enqueue[U >: T](x: U) = 
    new Queue[U](leading, x :: trailing) 
} 

औचित्य यह देखते हुए कि, जब तक कि यह दुष्प्रभाव ग्राहकों को दिखाई नहीं देते हैं, कुछ इस तरह कार्यात्मक माना जा सकता है। मुझे लगता है कि मैं इसके पीछे हो सकता हूं ... मेरा मतलब है कि कड़ाई से बोलना यही है जो एक समारोह को परिभाषित करता है। लेकिन स्वीकार्य रूप से (और मैं वास्तव में जेवीएम मेमोरी मॉडल की गारंटी के बारे में बहुत समझदार नहीं हूं), लेकिन क्या इस कोड में इसके साथ संभावित समस्याएं नहीं हैं?

उदाहरण के लिए, दो धागे इस कतार है, जो इस तरह दिखता है पर कार्रवाई चल रहे हैं शुरू करने के लिए:

Leading: Nil 
Trailing: List(1,2,3,4) 

यह संभव नहीं है कि एक धागा आईने में इस मुद्दे पर सिर() हो रही है कह सकते हैं() descheduled किए जाने से पहले:

private def mirror() = 
    if (leading.isEmpty) { 
     while (!trailing.isEmpty) { 
     leading = trailing.head :: leading 
     > trailing = trailing.tail 
     } 
    } 

जो बिंदु पर कतार इस तरह दिखता है:

Leading: List(1) 
Trailing: List(1,2,3,4) 

और जब एक दूसरे धागा पूंछ() जबकि पहले सक्रिय नहीं है, इस लौटा दिया जाएगा कॉल:

Leading: Nil 
Trailing: List(1,2,3,4) 

जबकि पहले धागा के सिर() कॉल समाप्त करने के लिए, यह एक बाद में पूंछ के बाद लौटा दिया जाएगा थे

Leading: List(2,3,4) 
Trailing: Nil 

मैं वैसे सामान और समवर्ती प्रोग्रामिंग वास्तव में, मेरे लिए mindbending है के रूप में मैं इसे बहुत से लोगों को के लिए है यकीन है, मैं कर रहा हूँ इस तरह से महान नहीं कर रहा हूँ:() उस सूची पर फोन बस उत्सुक है कि मैं यहाँ क्या खो रहा हूँ।

+0

मुझे लगता है कि आप सही हैं। मुझे लगता है कि आप कह सकते हैं कि "कार्यात्मक अनुभव" टूट जाता है यदि इसका उपयोग एक से अधिक धागे द्वारा किया जा रहा है। क्या कार्यात्मक कार्यक्रम निर्बाध रूप से समवर्ती होने चाहिए? मुझे नहीं पता। – Owen

उत्तर

3

आप सही हैं: कार्यात्मक दिखने वाले कोड को कई थ्रेड द्वारा उपयोग किए जाने पर गैर-कार्यात्मक प्रदान किया जा सकता है यदि यह कार्यान्वयन के हिस्से के रूप में आंतरिक स्थिति का उपयोग करता है। आप म्यूटेबल वैरिएबल को छूने वाली प्रत्येक विधि को सिंक्रनाइज़ करके इसे ठीक कर सकते हैं (यानी synchronized ब्लॉक के साथ)। दुर्भाग्यवश, यह प्रदर्शन के लिए आदर्श नहीं है, यही कारण है कि एक थ्रेडेड अनुप्रयोग कार्यात्मक कार्यान्वयन में अक्सर पसंद किया जाता है।

+0

ठीक है, बस यह सुनिश्चित करना चाहता था कि मैं पागल नहीं था। रियायत के साथ कि इन परिभाषाओं में घबराहट हो सकती है, या कम से कम उनके अर्थ का कुल समझौता नहीं हो सकता है ... क्या लेखकों के रूप में वास्तव में यह "पूरी तरह कार्यात्मक" या "अपरिवर्तनीय" कहना उचित है? यह सही परिस्थितियों में कार्यात्मक दिखता है, लेकिन यह निश्चित रूप से अपरिवर्तनीय नहीं है ... मेरा मतलब है कि यह राज्य को स्पष्ट रूप से बदलता है, और कार्यात्मक रूप कई धागे के साथ टूट जाता है। मैं पूछता हूं क्योंकि मैं लेखकों को लिखने के बारे में सोच रहा हूं और एक विशाल उपकरण की तरह दिखना नहीं चाहता हूं। –

+0

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

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