design हास्केल में बड़े पैमाने पर डिजाइन?




haskell functional-programming (7)

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

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

बड़े कार्यात्मक कार्यक्रमों को डिजाइन / ढांचा बनाने का एक अच्छा तरीका क्या है, खासकर हास्केल में?

मैं ट्यूटोरियल्स के एक गुच्छा के माध्यम से रहा हूं (रियल वर्ल्ड हास्केल के साथ एक करीबी दूसरा के साथ खुद को एक योजना लिखें, लेकिन अधिकांश कार्यक्रम अपेक्षाकृत छोटे हैं, और एकल उद्देश्य हैं। इसके अतिरिक्त, मैं उनमें से कुछ को विशेष रूप से सुरुचिपूर्ण होने पर विचार नहीं करता (उदाहरण के लिए, WYAS में विशाल लुकअप टेबल)।

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

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

क्या हास्केल के लिए समकक्ष साहित्य है? कार्यात्मक प्रोग्रामिंग (monads, तीर, आवेदक, आदि) में उपलब्ध विदेशी नियंत्रण संरचनाओं का चिड़ियाघर इस उद्देश्य के लिए सबसे अच्छा कैसे काम करता है? आप किस सर्वोत्तम प्रथाओं की सिफारिश कर सकते हैं?

धन्यवाद!

संपादित करें (यह डॉन स्टीवर्ट के उत्तर का अनुवर्ती है):

@ डोंस ने उल्लेख किया: "मोनाड्स प्रकारों में प्रमुख वास्तुशिल्प डिजाइनों को पकड़ते हैं।"

मुझे लगता है कि मेरा सवाल है: एक शुद्ध कार्यात्मक भाषा में महत्वपूर्ण वास्तुशिल्प डिजाइनों के बारे में कैसे सोचना चाहिए?

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

डेटा और पार्सिंग चरणों को एक अच्छे तरीके से बांधने का 'सही' तरीका क्या है? कोई एक बड़ा काम लिख सकता है जो विभिन्न डेटा प्रकारों के लिए सही काम करता है। या कोई भी अब तक संसाधित किए जाने वाले ट्रैक का ट्रैक रखने के लिए एक मोनड का उपयोग कर सकता है और प्रत्येक प्रसंस्करण चरण को मोनाड राज्य के आगे जो भी चाहिए उसे प्राप्त करें। या कोई बड़े पैमाने पर अलग कार्यक्रम लिख सकता है और संदेश भेज सकता है (मुझे इस विकल्प को बहुत पसंद नहीं है)।

जिन स्लाइडों से उन्होंने लिंक किया उनमें एक चीज है जिसे हमें बुलेट की आवश्यकता है: "प्रकार / कार्यों / कक्षाओं / monads पर डिजाइन मैपिंग के लिए मुहावरे"। मुहावरे क्या हैं? :)


डॉन ने आपको ऊपर दिए गए अधिकांश विवरण दिए हैं, लेकिन यहां मेरे दो सेंट हैं जो वास्तव में नट-किरकिरा राज्य कार्यक्रम जैसे हास्केल में सिस्टम डिमन्स कर रहे हैं।

  1. अंत में, आप एक मोनड ट्रांसफॉर्मर स्टैक में रहते हैं। नीचे आईओ है। इसके अलावा, प्रत्येक प्रमुख मॉड्यूल (अमूर्त अर्थ में, मॉड्यूल-इन-ए-फाइल भावना नहीं) उस स्टैक में एक परत में अपनी आवश्यक स्थिति को मानचित्र करता है। तो यदि आपके पास मॉड्यूल में अपना डेटाबेस कनेक्शन कोड छिपा हुआ है, तो आप इसे सभी प्रकार के मोनैड रीडर कनेक्शन m => ... -> m ... और फिर आपके डेटाबेस फ़ंक्शंस को अन्य कार्यों से बिना कनेक्शन के प्राप्त कर सकते हैं मॉड्यूल को इसके अस्तित्व से अवगत होना चाहिए। आप समानांतरता और सिंक्रनाइज़ेशन के समाधान के लिए अपने डेटाबेस कनेक्शन को ले जाने वाली एक परत के साथ समाप्त हो सकते हैं, एक और आपकी कॉन्फ़िगरेशन, एक तिहाई आपके विभिन्न सेमफोर और एमवार्स, आपकी लॉग फ़ाइल हैंडल इत्यादि।

  2. पहले अपनी त्रुटि हैंडलिंग को चित्रित करें । बड़े सिस्टम में हास्केल के लिए इस समय सबसे बड़ी कमजोरी त्रुटि प्रबंधन विधियों की अधिकता है, जिसमें शायद हंसमुख लोगों सहित (जो गलत है क्योंकि आप गलत होने पर किसी भी जानकारी को वापस नहीं कर सकते हैं; हमेशा जब तक आप वास्तव में उपयोग नहीं करते हैं बस मूल्य गुम मूल्य)। यह पता लगाएं कि आप इसे पहले कैसे करने जा रहे हैं, और अपने पुस्तकालयों और अन्य कोड को आपके अंतिम एक में उपयोग की जाने वाली विभिन्न त्रुटि हैंडलिंग तंत्र से एडाप्टर सेट अप करें। यह आपको बाद में दुःख की दुनिया बचाएगा।

अनुपूरक (टिप्पणियों से निकाला गया; Lii और liminalisht लिए धन्यवाद) -
एक बड़े कार्यक्रम को एक ढेर में मोनाड्स में टुकड़ा करने के विभिन्न तरीकों के बारे में अधिक चर्चा:

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


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

कार्यात्मक प्रोग्रामिंग का शिल्प

http://www.cs.kent.ac.uk/people/staff/sjt/craft2e/


हास्केल में बड़े कार्यक्रमों को डिजाइन करना अन्य भाषाओं में ऐसा करने से अलग नहीं है। बड़े पैमाने पर प्रोग्रामिंग आपके समस्या को प्रबंधनीय टुकड़ों में तोड़ने और उन लोगों को एक साथ फिट करने के बारे में है; कार्यान्वयन भाषा कम महत्वपूर्ण है।

उस ने कहा, एक बड़े डिजाइन में यह सुनिश्चित करने के लिए कि आप सही तरीके से अपने टुकड़ों को एक साथ फिट कर सकते हैं, यह सुनिश्चित करने के लिए टाइप सिस्टम को आजमाने और लीवरेज करना अच्छा होता है। इसमें ऐसी चीजें बनाने के लिए नए प्रकार या प्रेत प्रकार शामिल हो सकते हैं जो समान प्रकार के होते हैं।

जब आप कोड के साथ जाते हैं तो कोड को दोबारा करने की बात आती है, शुद्धता एक महान वरदान है, इसलिए जितना संभव हो उतना कोड को शुद्ध रखने की कोशिश करें। शुद्ध कोड रिफैक्टर के लिए आसान है, क्योंकि इसमें आपके प्रोग्राम के अन्य हिस्सों के साथ कोई छिपी बातचीत नहीं है।


मैं हास्केल में इंजीनियरिंग बड़े परियोजनाओं और एक्समोनाड के डिजाइन और कार्यान्वयन में इसके बारे में कुछ बात करता हूं। बड़े पैमाने पर इंजीनियरिंग जटिलता के प्रबंधन के बारे में है। जटिलता के प्रबंधन के लिए हास्केल में प्राथमिक कोड संरचना तंत्र हैं:

प्रकार प्रणाली

  • इंटरैक्शन को सरल बनाने, abstractions को लागू करने के लिए प्रकार प्रणाली का प्रयोग करें।
  • प्रकार के माध्यम से कुंजी invariants लागू करें
    • (उदाहरण के लिए कि कुछ मूल्य कुछ गुंजाइश से बच नहीं सकते हैं)
    • वह निश्चित कोड कोई आईओ नहीं करता है, डिस्क को स्पर्श नहीं करता है
  • सुरक्षा लागू करें: अपवादों की जांच (शायद / या तो), मिश्रण अवधारणाओं से बचें (शब्द, Int, पता)
  • अच्छी डेटा संरचनाएं (जैसे ज़िप्पर) परीक्षण के कुछ वर्गों को अनावश्यक बना सकती हैं, क्योंकि वे नियम बनाते हैं जैसे सीमाओं की त्रुटियों को स्थिर रूप से।

प्रोफाइलर

  • अपने कार्यक्रम के ढेर और समय प्रोफाइल के उद्देश्य सबूत प्रदान करें।
  • ढेर प्रोफाइलिंग, विशेष रूप से, कोई अनावश्यक स्मृति उपयोग सुनिश्चित करने का सबसे अच्छा तरीका नहीं है।

पवित्रता

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

परिक्षण

  • क्विक चेक + हास्केल कोड कवरेज, यह सुनिश्चित करने के लिए कि आप उन चीजों का परीक्षण कर रहे हैं जिन्हें आप प्रकारों से जांच नहीं सकते हैं।
  • जीएचसी + आरटीएस यह देखने के लिए बहुत अच्छा है कि क्या आप जीसी करने में बहुत अधिक समय बिता रहे हैं।
  • क्विक चेक आपको अपने मॉड्यूल के लिए स्वच्छ, ऑर्थोगोनल एपीआई की पहचान करने में भी मदद कर सकता है। यदि आपके कोड के गुणों को अवश्य कहना मुश्किल है, तो वे शायद बहुत जटिल हैं। रिफैक्टरिंग रखें जब तक कि आपके पास गुणों का एक साफ सेट न हो जो आपके कोड का परीक्षण कर सके, जो अच्छी तरह से लिखता है। फिर कोड शायद अच्छी तरह से डिजाइन किया गया है।

संरचना के लिए मोनाड्स

  • मोनाड्स प्रकारों में प्रमुख आर्किटेक्चरल डिज़ाइन कैप्चर करते हैं (यह कोड हार्डवेयर तक पहुंचता है, यह कोड एक एकल उपयोगकर्ता सत्र है, आदि)
  • Xmonad में एक्स monad के रूप में, सिस्टम के घटकों के लिए क्या राज्य दृश्यमान है के लिए सटीक डिजाइन कैप्चर करता है।

कक्षाएं और अस्तित्व के प्रकार टाइप करें

  • अमूर्तता प्रदान करने के लिए प्रकार वर्गों का उपयोग करें: पॉलिमॉर्फिक इंटरफेस के पीछे कार्यान्वयन छुपाएं।

समवर्ती और समांतरता

  • आसान, संगत समानांतरता के साथ प्रतिस्पर्धा को हरा करने के लिए अपने कार्यक्रम में घुसपैठ करें।

Refactor

  • आप हास्केल में बहुत कुछ कर सकते हैं। यदि आप समझदारी से प्रकार का उपयोग कर रहे हैं, तो प्रकारों को सुनिश्चित करें कि आपके बड़े पैमाने पर परिवर्तन सुरक्षित होंगे। यह आपके कोडबेस पैमाने में मदद करेगा। सुनिश्चित करें कि आपके रिफैक्टरिंग पूर्ण होने तक टाइप त्रुटियों का कारण बनेंगे।

बुद्धिमानी से एफएफआई का प्रयोग करें

  • एफएफआई विदेशी कोड के साथ खेलना आसान बनाता है, लेकिन वह विदेशी कोड खतरनाक हो सकता है।
  • लौटाए गए डेटा के आकार के बारे में धारणाओं में बहुत सावधान रहें।

मेटा प्रोग्रामिंग

  • टेम्पलेट हास्केल या जेनेरिक का एक बिट बॉयलरप्लेट को हटा सकता है।

पैकेजिंग और वितरण

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

चेतावनी

  • अपने कोड को गंध से साफ रखने के लिए उपयोग करें। आप अधिक आश्वासन के लिए एग्डा, इसाबेल या कैच को भी देख सकते हैं। लिंट की तरह जांच के लिए, महान hlint देखें, जो सुधारों का सुझाव देगा।

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

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


गेब्रियल का ब्लॉग पोस्ट स्केलेबल प्रोग्राम आर्किटेक्चर का उल्लेख उल्लेखनीय हो सकता है।

हास्केल डिज़ाइन पैटर्न मुख्यधारा के डिज़ाइन पैटर्न से एक महत्वपूर्ण तरीके से भिन्न होते हैं:

  • पारंपरिक वास्तुकला : टाइप बी के "नेटवर्क" या "टोपोलॉजी" उत्पन्न करने के लिए टाइप ए के साथ कई घटकों को एक साथ जोड़ें

  • हास्केल आर्किटेक्चर : एक ही प्रकार ए के एक नए घटक को उत्पन्न करने के लिए टाइप ए के साथ कई घटकों को एक साथ जोड़ें, इसके प्रतिस्थापन भागों से चरित्र में अलग-अलग

यह अक्सर मुझे मारता है कि एक स्पष्ट रूप से सुरुचिपूर्ण वास्तुकला अक्सर पुस्तकालयों से बाहर निकलती है जो एक समानता के तरीके में समानता की इस अच्छी भावना को प्रदर्शित करती हैं। हास्केल में यह विशेष रूप से स्पष्ट है - पारंपरिक रूप से "टॉप-डाउन आर्किटेक्चर" माना जाने वाला पैटर्न mvc , Netwire और क्लाउड हास्केल जैसे पुस्तकालयों में कब्जा कर लिया जाता है। ऐसा कहने के लिए, मुझे आशा है कि इस उत्तर को इस धागे में किसी भी अन्य व्यक्ति को प्रतिस्थापित करने के प्रयास के रूप में व्याख्या नहीं किया जाएगा, केवल संरचनात्मक विकल्प डोमेन विशेषज्ञों द्वारा पुस्तकालयों में आदर्श रूप से दूर किए जा सकते हैं। बड़ी राय बनाने में वास्तविक कठिनाई, मेरी राय में, इन पुस्तकालयों का मूल्यांकन उनके वास्तुशिल्प "भलाई" पर आपकी सभी व्यावहारिक चिंताओं के विरुद्ध है।

जैसा कि टिप्पणियों में liminalisht का उल्लेख है, श्रेणी डिजाइन पैटर्न एक समान नस में विषय पर गेब्रियल द्वारा एक और पोस्ट है।






large-scale