विशुद्ध रूप से कार्यात्मक भाषाएं मॉड्यूलरिटी को कैसे संभालती हैं?


23

मैं ऑब्जेक्ट ओरिएंटेड बैकग्राउंड से आता हूं, जहां मैंने सीखा है कि कक्षाएं हैं या कम से कम अमूर्तता की एक परत बनाने के लिए इस्तेमाल की जा सकती हैं जो कोड के आसान रीसाइक्लिंग के लिए अनुमति देता है जो तब या तो ऑब्जेक्ट बनाने के लिए उपयोग किया जा सकता है या विरासत में उपयोग किया जा सकता है।

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

मैं हाल ही में कार्यात्मक प्रोग्रामिंग में जा रहा हूं, इसलिए मुझे आश्चर्य हो रहा था:
विशुद्ध रूप से कार्यात्मक भाषाएं इस तरह की चीजों को कैसे संभालती हैं? वह है, किसी भी वर्ग और वस्तुओं की अवधारणा के बिना भाषाएँ।


1
आपको क्यों लगता है कि कार्यात्मक का मतलब कक्षाएं नहीं है? कुछ फ्रिस्ट क्लास एलआईएसपी से आए थे - क्लोजर नेमस्पेस और टाइप्स या मॉड्यूल और हैसेल में सीएलओएस देखें ।

मैंने उन कार्यात्मक भाषाओं का उल्लेख किया है जिनके पास कक्षाएं नहीं हैं, मुझे बहुत कम लोगों को पता है कि DO
इलेक्ट्रिक कॉफ़ी

1
एक उदाहरण के रूप में Caml, इसकी बहन भाषा OCaml वस्तुओं को जोड़ती है, लेकिन Caml खुद उन्हें नहीं है।
इलेक्ट्रिक कॉफी

12
शब्द "विशुद्ध रूप से कार्यात्मक" कार्यात्मक भाषाओं को संदर्भित करता है जो संदर्भात्मक पारदर्शिता को बनाए रखते हैं और इस बात से असंबंधित है कि क्या भाषा में कोई विशेष उन्नत विशेषताएं हैं या नहीं।
sepp2k

2
केक एक झूठ है, ओओ में कोड का पुन: उपयोग एफपी की तुलना में कहीं अधिक कठिन है। उन सभी के लिए, जिन्होंने वर्षों से OO ने कोड के पुन: उपयोग का दावा किया है, मैंने इसे कम से कम बार देखा है। (केवल यह कहने के लिए स्वतंत्र महसूस करें कि मुझे यह गलत करना चाहिए, मैं इस बात से सहज हूं कि मैं कितनी अच्छी तरह लिखता हूं ओओ कोड को डिजाइन करना और सालों तक ओओ सिस्टम को बनाए रखना है, मुझे अपने परिणामों की गुणवत्ता पता है)
जिमी हॉफ

जवाबों:


19

कई कार्यात्मक भाषाओं में एक मॉड्यूल सिस्टम होता है। (कई ऑब्जेक्ट-ओरिएंटेड भाषाएँ भी, वैसे)। लेकिन यहां तक ​​कि एक की अनुपस्थिति में, आप मॉड्यूल के रूप में फ़ंक्शन का उपयोग कर सकते हैं।

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

ओटोह, हास्केल और एमएल परिवार में एक स्पष्ट मॉड्यूल प्रणाली है।

ऑब्जेक्ट ओरिएंटेशन डेटा एब्स्ट्रक्शन के बारे में है। बस। प्रतिरूपकता, वंशानुक्रम, बहुरूपता, यहां तक ​​कि उत्परिवर्तनीय स्थिति भी ऑर्थोगोनल चिंताएं हैं।


8
क्या आप बता सकते हैं कि ऊप के संबंध में वे चीजें कैसे अधिक विस्तार से काम करती हैं? केवल यह कहने के बजाय कि अवधारणाएं मौजूद हैं ...
इलेक्ट्रिक कॉफी

सिडेनोट - मॉड्यूल और इकाइयां रैकेट में दो अलग-अलग निर्माण हैं - मॉड्यूल नामस्थानों की तुलना में हैं, और यूनिट नामस्थान और ओओ इंटरफेस के बीच आधे रास्ते की तरह हैं। डॉक्स मतभेदों पर बहुत अधिक विस्तार से जाते हैं
जैक

@ जैक: मुझे नहीं पता था कि रैकेट के पास एक अवधारणा भी है module। मुझे लगता है कि यह दुर्भाग्यपूर्ण है कि रैकेट के पास एक अवधारणा है जिसे moduleएक मॉड्यूल नहीं कहा जाता है, और एक अवधारणा जो एक मॉड्यूल है, लेकिन बुलाया नहीं है module। वैसे भी, आपने लिखा है: "इकाइयां नामस्थान और OO इंटरफेस के बीच आधे रास्ते की तरह हैं"। ठीक है, एक मॉड्यूल क्या है की परिभाषा की तरह नहीं है?
जोर्ग डब्ल्यू मित्तग

मॉड्यूल और इकाइयां दोनों ही मूल्यों के लिए बाध्य नामों के समूह हैं। मॉड्यूल में बाइंडिंग के अन्य विशिष्ट सेटों पर निर्भरता हो सकती है , जबकि इकाइयों में बाइंडिंग के कुछ सामान्य सेटों पर निर्भरता हो सकती है जो किसी अन्य कोड का उपयोग करता है जो यूनिट को प्रदान करना है। इकाइयों कर रहे हैं parameterized बाइंडिंग से अधिक, मॉड्यूल नहीं हैं। एक बाइंडिंग पर निर्भर एक मॉड्यूल mapऔर एक बाइंडिंग पर निर्भर एक यूनिट mapअलग है जिसमें मॉड्यूल को कुछ विशिष्ट बाइंडिंग का उल्लेख करना चाहिएmap , जैसे कि एक से racket/base, जबकि यूनिट के विभिन्न उपयोगकर्ता यूनिट की अलग-अलग परिभाषा दे सकते हैं map
जैक

4

ऐसा लगता है कि आप दो प्रश्न पूछ रहे हैं: "आप कार्यात्मक भाषाओं में मॉड्यूलरिटी कैसे प्राप्त कर सकते हैं?" जिसे अन्य उत्तरों में निपटाया गया है और "आप कार्यात्मक भाषाओं में सार कैसे बना सकते हैं?" मैं जवाब दूंगा।

OO भाषाओं में, आप संज्ञा पर ध्यान केंद्रित करते हैं, "एक जानवर", "डाकिया", "उसका बगीचा कांटा" आदि, कार्यात्मक भाषाएं, इसके विपरीत, क्रिया पर जोर दें, "चलने के लिए", "मेल लाने के लिए" , "को ठेस", आदि

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

इसका एक और ठोस उदाहरण एक परियोजना है जिसे मैं बहुत पहले से काम नहीं कर रहा था। मैं हास्केल में एक डेटाबेस लिख रहा था। मेरे पास निम्नतम स्तर पर परिचालन निर्दिष्ट करने के लिए एक 'एम्बेडेड भाषा' थी; उदाहरण के लिए, इसने मुझे भंडारण माध्यम से चीजों को लिखने और पढ़ने की अनुमति दी। उच्चतम स्तर पर परिचालन निर्दिष्ट करने के लिए मेरे पास एक और, अलग, 'एम्बेडेड भाषा' थी। तब मेरे पास उच्च स्तर से निचले स्तर तक संचालन को बदलने के लिए अनिवार्य रूप से एक दुभाषिया था।

यह अमूर्तता का एक सामान्य रूप है, लेकिन यह केवल कार्यात्मक भाषाओं में उपलब्ध नहीं है।


4

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

परंपरागत रूप से टाइप की गई ओओपी भाषाएं पारंपरिक रूप से नाममात्र सबटाइपिंग का उपयोग करती हैं, जिसका अर्थ है कि वर्ग / मॉड्यूल / इंटरफ़ेस ए के लिए डिज़ाइन किया गया कोड केवल वर्ग / मॉड्यूल / इंटरफ़ेस बी के साथ सौदा कर सकता है जब बी स्पष्ट रूप से उल्लेख करता है। कार्यात्मक प्रोग्रामिंग परिवार में भाषाएं मुख्य रूप से संरचनात्मक उप-प्रकार का उपयोग करती हैं, जिसका अर्थ है A के लिए डिज़ाइन किया गया वह कोड जब भी B को संभाल सकता है, B के पास सभी तरीके और / या फ़ील्ड हो सकते हैं। B का एक अलग टीम द्वारा बनाया जा सकता है इससे पहले कि अधिक सामान्य वर्ग / इंटरफ़ेस की आवश्यकता थी। A. उदाहरण के लिए OCaml में, संरचनात्मक सबटाइपिंग मॉड्यूल सिस्टम पर लागू होता है, ओओपी-जैसे ऑब्जेक्ट सिस्टम, और इसके काफी अद्वितीय बहुरूपी प्रकार।

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

स्काला में ओओपी और एफपी का संयोजन इसे सबसे शक्तिशाली भाषाओं में से एक बना सकता है। प्रतिरूपकता। लेकिन OCaml अभी भी मेरी पसंदीदा भाषा है और मेरी व्यक्तिगत, व्यक्तिपरक राय में यह स्काला की कमी नहीं है। नीचे दिए गए दो राल्फ लामेल व्याख्यान हास्केल में अभिव्यक्ति समस्या के समाधान पर चर्चा करते हैं। मुझे लगता है कि यह समाधान, हालांकि पूरी तरह से काम कर रहा है, इसके परिणामस्वरूप पैरामीट्रिक बहुरूपता के साथ परिणामी डेटा का उपयोग करना मुश्किल है। OCaml में बहुरूपताओं के साथ अभिव्यक्ति की समस्या को हल करते हुए, नीचे दिए गए Jaques Garrigue लेख में समझाया गया है, जिसमें यह कमी नहीं है। मैं पाठ्यपुस्तक के अध्यायों से भी जुड़ता हूं, जो कि OCaml में गैर-OOP और OOP प्रतिरूपकता के उपयोग की तुलना करते हैं।

नीचे Haskell- और OCaml- विशिष्ट लिंक एक्सप्रेशन समस्या पर विस्तार कर रहे हैं :


2
क्या आप इन संसाधनों पर क्या करते हैं और इस सवाल का जवाब देने के लिए इनकी सिफारिश करने के बारे में अधिक जानकारी प्राप्त करने का मन करेंगे? स्टैक एक्सचेंज में "लिंक-ओनली जवाब" का बहुत स्वागत नहीं है
gnat

2
मैंने केवल एक लिंक के रूप में, केवल लिंक के बजाय एक वास्तविक उत्तर प्रदान किया है।
लुकास्टफी

0

वास्तव में, OO कोड बहुत कम पुन: प्रयोज्य है, और यह डिजाइन द्वारा है। OOP के पीछे का विचार कुछ विशेषाधिकार प्राप्त कोड के लिए डेटा के विशेष टुकड़ों पर संचालन को प्रतिबंधित करना है जो या तो वर्ग में या वंशानुक्रम पदानुक्रम में उपयुक्त स्थान पर है। यह परिवर्तनशीलता के प्रतिकूल प्रभावों को सीमित करता है। यदि एक डेटा संरचना बदलती है, तो कोड में केवल कई स्थान हैं जो जिम्मेदार हो सकते हैं।

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

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

अपना Animalउदाहरण लें , और एक खिला सुविधा को लागू करने पर विचार करें। सीधा ओओपी कार्यान्वयन Animalवस्तुओं के संग्रह को बनाए रखना है , और उन सभी के माध्यम से लूप करना है, उनमें से feedप्रत्येक पर विधि को कॉल करना है।

हालांकि, जब आप विवरण के लिए नीचे आते हैं तो चीजें मुश्किल हो जाती हैं। एक Animalवस्तु स्वाभाविक रूप से जानती है कि वह किस तरह का भोजन खाती है, और उसे पूरा महसूस करने के लिए उसे कितना खाना चाहिए। यह स्वाभाविक रूप से नहीं जानता कि भोजन कहाँ रखा गया है और कितना उपलब्ध है, इसलिए एक FoodStoreवस्तु बस हर एक की निर्भरता बन गई है Animal, या तो Animalवस्तु के एक क्षेत्र के रूप में, या feedविधि के एक पैरामीटर के रूप में पारित किया गया है। वैकल्पिक रूप से, रखने के लिए Animalवर्ग अधिक एकजुट, आप ले सकते हैं feed(animal)करने के लिए FoodStoreवस्तु, या आप एक नामक एक वर्ग का abomination बना सकता है AnimalFeederया कुछ इस तरह।

एफपी में, ए के क्षेत्रों के Animalलिए हमेशा एक साथ रहने के लिए झुकाव नहीं होता है , जिसमें पुन: प्रयोज्य के लिए कुछ दिलचस्प निहितार्थ हैं। आप की एक सूची है कहो Animalरिकॉर्ड, क्षेत्रों की तरह साथ name, species, location, food type, food amount, आदि तुम भी की एक सूची है FoodStoreरिकॉर्ड जैसे क्षेत्रों के साथ location, food type, और food amount

खिला में पहला कदम (food amount, food type)जानवरों की राशियों के लिए ऋणात्मक संख्याओं के साथ उन सूचियों के प्रत्येक रिकॉर्ड को जोड़े की सूचियों में मैप करना हो सकता है । फिर आप इन जोड़े के साथ सभी प्रकार के काम करने के लिए फ़ंक्शंस बना सकते हैं, जैसे प्रत्येक प्रकार के भोजन की मात्रा। ये फ़ंक्शन Animalया तो पूरी तरह से या एक FoodStoreमॉड्यूल से संबंधित नहीं हैं , लेकिन दोनों द्वारा अत्यधिक पुन: प्रयोज्य हैं।

आप फ़ंक्शंस के एक समूह के साथ समाप्त [(Num A, Eq B)]होते हैं जो उस के साथ उपयोगी सामान करते हैं, पुन: प्रयोज्य और मॉड्यूलर होते हैं, लेकिन आपको यह पता लगाने में परेशानी होती है कि उन्हें कहां रखा जाए या उन्हें एक समूह के रूप में क्या कहा जाए। इसका प्रभाव यह है कि एफपी मॉड्यूल को वर्गीकृत करना अधिक कठिन है, लेकिन वर्गीकरण बहुत कम महत्वपूर्ण है।


-1

लोकप्रिय समाधानों में से एक, कोड को मॉड्यूल में तोड़ना है, यहां बताया गया है कि यह जावास्क्रिप्ट में कैसे किया जाता है:

    media.podcast = (function(name) {
    var fileExtension = 'mp3';        

     function determineFileExtension() {
         console.log('File extension is of type ' + fileExtension);
     }

     return {
         download: function(episode) {
            console.log('Downloading ' + episode + ' of ' + name);
            determineFileExtension();
        }
    }    
}('Astronomy podcast'));

पूरा लेख जावास्क्रिप्ट में इस पद्धति समझा , इसके अलावा इस तरह के रूप में एक मॉड्यूल को परिभाषित करने के अन्य तरीकों, की संख्या है RequireJS , CommonJS , गूगल बंद। एक अन्य उदाहरण एरलैंग है, जहां आपके पास मॉड्यूल और व्यवहार दोनों हैं जो एपीआई और पैटर्न को लागू करते हैं, ओओपी में इंटरफेसेस के समान भूमिका निभाते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.