जैसा कि यानिस ने बताया, कई ऐसे कारक हैं जिन्होंने पहले से बिना भाषाओं में उच्च-क्रम के कार्यों को अपनाने को प्रभावित किया है। महत्वपूर्ण वस्तुओं में से एक जिसे उन्होंने केवल हल्के से छुआ है वह मल्टी-कोर प्रोसेसर का प्रसार है और इसके साथ, अधिक समानांतर और समवर्ती प्रसंस्करण की इच्छा है।
कार्यात्मक प्रोग्रामिंग का नक्शा / फ़िल्टर / कम करने की शैली समानांतरकरण के लिए बहुत अनुकूल है, जिससे प्रोग्रामर आसानी से कई कोर का उपयोग कर सकता है, बिना किसी स्पष्ट थ्रेडिंग कोड को लिखे।
जियोर्जियो नोट के रूप में, केवल उच्च-ऑर्डर फ़ंक्शन की तुलना में कार्यात्मक प्रोग्रामिंग के लिए अधिक है। फ़ंक्शंस, प्लस एक नक्शा / फ़िल्टर / प्रोग्रामिंग पैटर्न को कम, और अपरिवर्तनीयता कार्यात्मक प्रोग्रामिंग का मूल है। साथ में ये चीजें समानांतर और समवर्ती प्रोग्रामिंग के शक्तिशाली उपकरण बनाती हैं। शुक्र है, कई भाषाएं पहले से ही अपरिवर्तनीयता की कुछ धारणा का समर्थन करती हैं, और, भले ही वे नहीं करते हैं, प्रोग्रामर चीजों को अपरिवर्तनीय रूप से पुस्तकालयों और संकलक को अतुल्यकालिक या समानांतर संचालन बनाने और प्रबंधित करने की अनुमति दे सकते हैं।
समवर्ती प्रोग्रामिंग को सरल बनाने के लिए एक भाषा में उच्च-क्रम के कार्यों को जोड़ना एक महत्वपूर्ण कदम है।
अपडेट करें
लोकी द्वारा बताई गई चिंताओं को दूर करने के लिए मैं कुछ और विस्तृत उदाहरण जोड़ूंगा।
निम्नलिखित सी # कोड पर विचार करें जो विजेट्स के संग्रह का पता लगाता है, जो विजेट की कीमतों की एक नई सूची बनाता है।
List<float> widgetPrices;
float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}
विगेट्स के एक बड़े संग्रह के लिए, या एक कम्प्यूटेशनल रूप से सघन कैलक्सेटविटगेटप्राइस (विजेट) विधि के लिए, यह लूप किसी भी उपलब्ध कोर का अच्छा उपयोग नहीं करेगा। अलग-अलग कोर पर मूल्य गणना करने के लिए प्रोग्रामर को स्पष्ट रूप से थ्रेड्स बनाने और प्रबंधित करने, चारों ओर काम करने और परिणामों को एक साथ इकट्ठा करने की आवश्यकता होगी।
एक बार उच्च-क्रम वाले कार्यों को C # में शामिल करने पर समाधान पर विचार करें:
var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );
इसके कार्यान्वयन के विवरण को छिपाते हुए, फॉर्च लूप को चयन विधि में स्थानांतरित कर दिया गया है। प्रोग्रामर को जो कुछ भी रहता है, उसे यह बताना है कि प्रत्येक तत्व के लिए क्या फ़ंक्शन चुनें। यह चयनकर्ता को प्रोग्रामर की भागीदारी के बिना सभी सिंक्रनाइज़ेशन और थ्रेड प्रबंधन चिंताओं से निपटने के लिए पैरेलल में गणना को चलाने की अनुमति देगा।
लेकिन, ज़ाहिर है, का चयन नहीं करते हैं यह समानांतर में काम करता है। यही वह जगह है जहाँ अपरिवर्तनीयता आती है। चयन के कार्यान्वयन को नहीं पता है कि प्रदान किए गए फ़ंक्शन (ऊपर की गणना) का साइड इफेक्ट नहीं है। फ़ंक्शन, सब कुछ तोड़कर चयन और उसके सिंक्रनाइज़ेशन के दृश्य के बाहर कार्यक्रम की स्थिति को बदल सकता है। उदाहरण के लिए, इस मामले में सेल्सटैक्स के मूल्य को गलती से बदला जा सकता है। शुद्ध कार्यात्मक भाषाएँ अपरिवर्तनीयता प्रदान करती हैं, इसलिए चयन (नक्शा) फ़ंक्शन यह सुनिश्चित कर सकता है कि कोई भी राज्य नहीं बदल रहा है।
Linq के विकल्प के रूप में PLINQ प्रदान करके C # इसे संबोधित करता है। ऐसा लगेगा:
var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );
जो उन तंत्रों के स्पष्ट प्रबंधन के बिना आपके सिस्टम के सभी कोर का पूर्ण उपयोग करता है।