हो सकता है कि आपने अभी कार्यात्मक प्रोग्रामिंग के बारे में सुना हो और आपके कुछ प्रश्न हों।
लाइक...
- कार्यात्मक प्रोग्रामिंग वास्तव में क्या है?
- यह ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग से कैसे तुलना करता है?
- क्या आपको रूबी में कार्यात्मक प्रोग्रामिंग का उपयोग करना चाहिए?
आइए मैं आपके लिए इन सवालों के जवाब देता हूं ताकि आप बेहतर तरीके से समझ सकें कि यह कैसे काम करता है।
कार्यात्मक प्रोग्रामिंग क्या है?
यह केवल एक सनक या फैंसी शब्द नहीं है, यह एक वास्तविक प्रोग्रामिंग प्रतिमान है जो लंबे समय से आसपास रहा है लेकिन हाल ही में इसने लोकप्रियता हासिल की है।
और इस प्रतिमान के पीछे मूल विचार आपके विचार से समझने में आसान हैं।
कार्यात्मक प्रोग्रामिंग में हम स्थिति बदलने से बचते हैं और हम "शुद्ध" फ़ंक्शंस write लिखने का प्रयास करते हैं ।
राज्य परिवर्तन से बचने का मतलब है कि ये फ़ंक्शन फ़ंक्शन के बाहर कुछ भी नहीं बदलते हैं, कोई आवृत्ति चर नहीं है, कोई ऑब्जेक्ट नहीं बदल रहा है जो पारित किया गया था…
इनमें से कोई नहीं!
एक कार्यात्मक प्रोग्रामिंग भाषा (जैसे हास्केल) में सभी डेटा अपरिवर्तनीय है।
चर जैसी चीजें हैं, लेकिन वे गणितीय दुनिया की तरह अधिक व्यवहार करते हैं। एक बार एक वैरिएबल को एक मान दिया जाता है, तो कंपाइलर आपको इस वेरिएबल को दूसरे मान के साथ फिर से परिभाषित करने की अनुमति नहीं देगा।
कार्यात्मक प्रोग्रामिंग के लाभ
अपरिवर्तनीयता कार्यात्मक प्रोग्रामिंग का मुख्य लाभ है क्योंकि परिवर्तनशील डेटा से सूक्ष्म त्रुटियां हो सकती हैं जिन्हें ट्रैक करना कठिन होता है।
उदाहरण :
def all_different_from_first?(arr) first = arr.shift arr.all? { |n| n != first } end arr = [1,3,5,7,9] p all_different_from_first?(arr) # true
इस उदाहरण में मैं यह पता लगाना चाहता हूं कि सरणी के सभी तत्व पहले तत्व से अलग हैं या नहीं।
इस कार्य को करने के लिए हमें पहले तत्व को सरणी से निकालना होगा और साथ ही इस तत्व को सहेजना होगा ताकि हम इसकी तुलना बाकी तत्वों से कर सकें।
हम यह कैसे कर सकते हैं?
हम एक सरणी के साथ काम कर रहे हैं और यदि आप उपलब्ध विधियों की सूची पर एक नज़र डालते हैं तो आप पाएंगे कि Array#shift विधि ठीक वही करती है जो हम चाहते हैं।
यह तब तक ठीक काम करता है जब तक...
...आप arr
. का मान देखें विधि को एक बार कॉल करने के बाद:
all_different_from_first?(arr) # true arr # [3,5,7,9]
आश्चर्य!
सरणी ने एक तत्व खो दिया (1
) और हमने ध्यान नहीं दिया।
इस तरह के परिवर्तनशीलता बग कितने डरपोक हो सकते हैं।
निश्चित संस्करण :
def all_different_from_first?(arr) arr[1..-1].all? { |n| n != arr.first } end
कार्यात्मक बनाम OOP
क्या हम सभी को केवल कार्यात्मक प्रोग्रामिंग अपनानी चाहिए?
ऐसा लग सकता है कि यह सभी अपरिवर्तनीय स्थिति कार्यात्मक प्रोग्रामिंग को OOP के पूर्ण विपरीत बनाती है, और एक अर्थ में यह है, लेकिन अभी भी एक तरीका है कि दो प्रोग्रामिंग प्रतिमान एक साथ काम कर सकते हैं ।
तो नहीं, फुल-ऑन फंक्शनल प्रोग्रामिंग में जल्दबाजी करने और जाने की कोई जरूरत नहीं है। रूबी को वैसे भी OOP के लिए डिज़ाइन किया गया है, इसलिए आप अनाज के खिलाफ़ लड़ रहे होंगे।
खुशखबरी :
आप अभी भी कार्यात्मक प्रोग्रामिंग से सर्वोत्तम विचारों का उपयोग कर सकते हैं और उन्हें अपने रूबी कोड पर लागू कर सकते हैं।
आइए बात करते हैं कि यह कैसे करना है।
म्यूटेबिलिटी को जितना हो सके कम करें
ऐसा करने का एक तरीका attr_accessor
. का उपयोग करके STOP करना है , केवल attr_reader
. से चिपके रहें ।
ऐसा करने के बाद आपको स्ट्रिंग्स, एरेज़ और हैश पर नज़र रखने की ज़रूरत है।
ऐसे तरीके हैं जो इन वस्तुओं को बदल देंगे:
- अधिकांश विधियां
!
(जैसेgsub!
) - हटाएं
- अपडेट करें
- साफ़
- शिफ्ट/अनशिफ्ट/पॉप/पुश
पहला कदम इन तरीकों से अवगत होना है।
अगर आपको इनमें से किसी एक तरीके का इस्तेमाल करना है तो आप एक डुप्लीकेट ऑब्जेक्ट पर काम कर सकते हैं।
एक स्ट्रिंग और उस स्ट्रिंग के क्लोन को देखते हुए :
str = "abcd" dup = str.dup
हमें ये परिणाम तब मिलते हैं जब हम clear
. करते हैं डुप्लीकेट स्ट्रिंग:
dup.clear # str => "abcd" # dup => ""
यह मूल स्ट्रिंग को सुरक्षित रखता है।
आंशिक आवेदन
अपरिवर्तनीय डेटा और शुद्ध कार्यों की तुलना में कार्यात्मक प्रोग्रामिंग के लिए और भी कुछ है।
कार्यों के आंशिक अनुप्रयोग की तरह, जिसे "करीइंग" भी कहा जाता है।
उदाहरण :
def add(a,b) a + b end add_five = method(:add).curry[5] add_five.call(5) # 10 add_five.call(20) # 25
ध्यान दें कि कैसे add
विधि में दो तर्क होते हैं, लेकिन curry
. का उपयोग करके विधि हम तर्कों में से एक को "प्रीलोड" कर सकते हैं।
फिर हमें एक लैम्ब्डा मिलता है जिसे हम केवल दूसरे तर्क के साथ कॉल कर सकते हैं।
यहां एक और उदाहरण दिया गया है :
list = (1..10) greater_than = ->(x,y) { y > x }.curry list.select(&greater_than.(5)) # [6, 7, 8, 9, 10] list.select(&greater_than.(8)) # [9, 10]
एक और उदाहरण :
divisible_by = ->(x,y) { y % x == 0 }.curry list.select(&divisible_by.(5)) # [5, 10] list.select(&divisible_by.(2)) # [2, 4, 6, 8, 10]
सारांश
आपने कार्यात्मक प्रोग्रामिंग के बारे में सीखा है, इसका मूल शुद्ध कार्य और अपरिवर्तनीय डेटा है, यह आपके कोड के बारे में सोचने का एक तरीका है और ओओपी के साथ पूरी तरह से असंगत नहीं है।
पढ़ने के लिए धन्यवाद, यदि आपने अभी तक न्यूज़लेटर की सदस्यता नहीं ली है तो सदस्यता लेना न भूलें!