यह जवाब इलिस्सियस द्वारा उठाए गए मुद्दों के जवाब में है, बिंदु द्वारा बिंदु:
- इसका उपयोग करना बदसूरत है। $ (fooBar '' Asdf) बस अच्छा नहीं लगता। सतही, सुनिश्चित, लेकिन यह योगदान देता है।
मैं सहमत हूँ। मुझे ऐसा लग रहा है कि $ () देखने के लिए चुना गया था क्योंकि यह भाषा का हिस्सा था - हास्केल के परिचित प्रतीक फूस का उपयोग करके। हालाँकि, यह वही है जो आप अपने मैक्रो स्प्लिसिंग के लिए उपयोग किए जाने वाले प्रतीकों में / नहीं / चाहते हैं। वे निश्चित रूप से बहुत अधिक मात्रा में मिश्रण करते हैं, और यह कॉस्मेटिक पहलू काफी महत्वपूर्ण है। मुझे स्पिलेस के लिए {{}} का लुक पसंद है, क्योंकि वे काफी नेत्रहीन हैं।
- यह लिखना भी बदसूरत है। क्वोटिंग कभी-कभी काम करता है, लेकिन बहुत बार आपको मैनुअल एएसटी ग्राफ्टिंग और प्लंबिंग करना पड़ता है। [एपीआई] [१] बड़ा और अलौकिक है, ऐसे बहुत से मामले हैं जिनकी आपको परवाह नहीं है, लेकिन फिर भी उन्हें प्रेषण करने की आवश्यकता है, और जिन मामलों की आप परवाह करते हैं, वे कई समान हैं, लेकिन समान रूपों में मौजूद नहीं हैं (डेटा बनाम न्यूटाइप, रिकॉर्ड-स्टाइल बनाम सामान्य कंस्ट्रक्टर, और इसी तरह)। यह लिखने के लिए उबाऊ और दोहराव है और यांत्रिक नहीं होने के लिए पर्याप्त जटिल है। [सुधार प्रस्ताव] [2] इसमें से कुछ को संबोधित करते हैं (उद्धरण को अधिक व्यापक रूप से लागू करते हैं)।
मैं इस बात से भी सहमत हूं, हालांकि, "टीएच के लिए नई दिशाएं" टिप्पणियों में से कुछ के रूप में, अच्छा आउट-ऑफ-द-बॉक्स एएसटी उद्धरण की कमी एक महत्वपूर्ण दोष नहीं है। इस WIP पैकेज में, मैं इन समस्याओं को लाइब्रेरी रूप में संबोधित करना चाहता हूं: https://github.com/mgsloan/quasi-extras । अब तक मैं सामान्य से कुछ अधिक स्थानों पर स्प्लिसिंग की अनुमति देता हूं और एएसटीएस पर मैच कर सकता हूं।
- चरण प्रतिबंध नरक है। एक ही मॉड्यूल में परिभाषित कार्यों को विभाजित करने में सक्षम नहीं होना इसका एक छोटा हिस्सा है: दूसरा परिणाम यह है कि यदि आपके पास एक शीर्ष-स्तरीय विभाजन है, तो मॉड्यूल में इसके बाद की हर चीज इसके दायरे से बाहर हो जाएगी। इस संपत्ति के साथ अन्य भाषाएं (C, C ++) आपको चीजों को अग्रेषित करने की अनुमति देकर इसे काम करने योग्य बनाती हैं, लेकिन हास्केल नहीं करता है। यदि आपको spliced घोषणाओं या उनकी निर्भरता और आश्रितों के बीच चक्रीय संदर्भों की आवश्यकता है, तो आप आमतौर पर केवल खराब कर दिए जाते हैं।
मैं चक्रीय टीएच परिभाषाओं के मुद्दे पर पहले भी असंभव रहा हूं ... यह काफी कष्टप्रद है। एक समाधान है, लेकिन यह बदसूरत है - एक TH अभिव्यक्ति में चक्रीय निर्भरता में शामिल चीजों को लपेटें जो सभी उत्पन्न घोषणाओं को जोड़ती है। इन घोषणाओं में से एक जनरेटर सिर्फ एक अर्ध-उद्धरण हो सकता है जो हास्केल कोड को स्वीकार करता है।
- यह अपूर्व है। इससे मेरा अभिप्राय यह है कि जब आप अमूर्त को व्यक्त करते हैं, तो उस अमूर्त के पीछे किसी प्रकार का सिद्धांत या अवधारणा होती है। कई सार के लिए, उनके पीछे के सिद्धांत को उनके प्रकारों में व्यक्त किया जा सकता है। जब आप एक प्रकार की कक्षा को परिभाषित करते हैं, तो आप अक्सर कानून बना सकते हैं जो उदाहरणों का पालन करना चाहिए और ग्राहक मान सकते हैं। यदि आप GHC की [नई जेनरिक विशेषता] का उपयोग करते हैं [3] तो किसी भी डेटाटाइप (सीमा के भीतर) पर एक उदाहरण घोषणा के रूप को सार करने के लिए, आपको "प्रकारों के लिए" कहना होगा, यह इस तरह से काम करता है, उत्पाद प्रकारों के लिए, यह उस तरह से काम करता है "। लेकिन टेम्पलेट हास्केल सिर्फ गूंगा मैक्रोज़ है। यह विचारों के स्तर पर अमूर्त नहीं है, लेकिन एएसटी के स्तर पर अमूर्तता, जो कि बेहतर है, लेकिन केवल मामूली पाठ के स्तर पर अमूर्तता से बेहतर है।
यदि आप इसके साथ अप्रत्याशित चीजें करते हैं तो यह केवल अप्रत्याशित है। अंतर केवल इतना है कि संकलक के लिए संकलक कार्यान्वित तंत्र के साथ, आपको अधिक विश्वास है कि अमूर्त रिसाव नहीं है। शायद लोकतांत्रिक भाषा डिजाइन थोड़ा डरावना लगता है! TH पुस्तकालयों के रचनाकारों को अच्छी तरह से दस्तावेज़ बनाने और उनके द्वारा प्रदान किए जाने वाले उपकरणों के अर्थ और परिणामों को स्पष्ट रूप से परिभाषित करने की आवश्यकता है। प्रिंसिपल TH का एक अच्छा उदाहरण व्युत्पन्न पैकेज है: http://hackage.haskell.org/package/derive - यह एक DSL का उपयोग करता है जैसे कि व्युत्पन्न / निर्दिष्ट / वास्तविक व्युत्पत्ति में से कई का उदाहरण।
- यह आपको जीएचसी से जोड़ता है। सिद्धांत रूप में एक और संकलक इसे लागू कर सकता है, लेकिन व्यवहार में मुझे संदेह है कि यह कभी भी होगा। (यह विभिन्न प्रकार के सिस्टम एक्सटेंशनों के विपरीत है, जो कि वर्तमान में केवल जीएचसी द्वारा लागू किए जा सकते हैं, मैं आसानी से सड़क के नीचे अन्य कंपाइलरों द्वारा अपनाए जाने की कल्पना कर सकता हूं और अंततः मानकीकृत हो सकता हूं।)
यह एक बहुत अच्छा बिंदु है - TH एपीआई बहुत बड़ा और स्पष्ट है। इसे फिर से लागू करना ऐसा लगता है कि यह कठिन हो सकता है। हालांकि, हास्केल एएसटीएस का प्रतिनिधित्व करने की समस्या को समाप्त करने के केवल कुछ ही तरीके हैं। मुझे लगता है कि TH ADTs की प्रतिलिपि बनाना, और आंतरिक एएसटी प्रतिनिधित्व के लिए एक कनवर्टर लिखना आपको वहां के तरीके का एक अच्छा सौदा मिलेगा। यह haskell-src-meta बनाने के (तुच्छ नहीं) प्रयास के बराबर होगा। यह केवल TH AST को सुंदर रूप से प्रिंट करके और संकलक के आंतरिक पार्सर का उपयोग करके फिर से लागू किया जा सकता है।
जबकि मैं गलत हो सकता है, मैं TH को एक कार्यान्वयन दृष्टिकोण के आधार पर एक कंपाइलर एक्सटेंशन के जटिल होने के रूप में नहीं देखता हूं। यह वास्तव में "इसे सरल रखने" के लाभों में से एक है और मौलिक परत न होने पर कुछ सैद्धांतिक रूप से आकर्षक, वैधानिक रूप से सत्यापित करने वाली प्रणाली है।
- एपीआई स्थिर नहीं है। जब GHC में नई भाषा सुविधाएँ जोड़ी जाती हैं और उनका समर्थन करने के लिए टेम्प्लेट-हैस्केल पैकेज अपडेट किया जाता है, तो इसमें अक्सर TH डेटाैटिप्स में पीछे-असंगत परिवर्तन शामिल होते हैं। यदि आप चाहते हैं कि आपका TH कोड GHC के सिर्फ एक से अधिक संस्करण के साथ संगत हो, तो आपको बहुत सावधान रहने और संभवतः उपयोग करने की आवश्यकता है
CPP
।
यह भी एक अच्छी बात है, लेकिन कुछ हद तक नाटकीय है। जबकि वहाँ हाल ही में एपीआई परिवर्धन किया गया है, वे बड़े पैमाने पर टूटने उत्प्रेरण नहीं किया गया है। इसके अलावा, मुझे लगता है कि मैंने पहले उल्लेख किए गए बेहतर एएसटी उद्धरण के साथ, एपीआई जिसे वास्तव में उपयोग करने की आवश्यकता है, उसे बहुत कम किया जा सकता है। यदि किसी निर्माण / मिलान के लिए अलग-अलग कार्यों की आवश्यकता होती है, और इसके बजाय उन्हें शाब्दिक रूप में व्यक्त किया जाता है, तो अधिकांश एपीआई गायब हो जाते हैं। इसके अलावा, आपके द्वारा लिखा गया कोड Haskell जैसी भाषाओं के लिए AST अभ्यावेदन के लिए अधिक आसानी से पोर्ट करेगा।
सारांश में, मुझे लगता है कि TH एक शक्तिशाली, अर्ध-उपेक्षित उपकरण है। कम घृणा पुस्तकालयों के अधिक जीवंत इको-सिस्टम को जन्म दे सकती है, जो अधिक भाषा सुविधा प्रोटोटाइप के कार्यान्वयन को प्रोत्साहित करती है। यह देखा गया है कि TH एक अधिकता वाला उपकरण है, जो आपको कुछ भी कर सकता है / कर सकता है। अराजकता! खैर, यह मेरी राय है कि यह शक्ति आपको इसकी अधिकांश सीमाओं को पार करने की अनुमति दे सकती है, और काफी राजसी मेटा-प्रोग्रामिंग दृष्टिकोणों में सक्षम सिस्टम का निर्माण कर सकती है। यह "उचित" कार्यान्वयन को अनुकरण करने के लिए बदसूरत हैक्स के उपयोग के लायक है, क्योंकि इस तरह "उचित" कार्यान्वयन का डिज़ाइन धीरे-धीरे स्पष्ट होगा।
निर्वाण के मेरे व्यक्तिगत आदर्श संस्करण में, भाषा का अधिकांश भाग वास्तव में संकलक से हटकर, इन विविधता के पुस्तकालयों में होगा। तथ्य यह है कि सुविधाओं को पुस्तकालयों के रूप में लागू किया जाता है, उनकी क्षमता को विश्वासपूर्वक अमूर्त करने के लिए बहुत अधिक प्रभावित नहीं करता है।
बॉयलरप्लेट कोड के लिए विशिष्ट हास्केल उत्तर क्या है? अमूर्त। हमारे पसंदीदा सार क्या हैं? फ़ंक्शंस और टाइपकास्ट!
टाइपकास्ट हमें विधियों का एक सेट परिभाषित करते हैं, जो तब उस वर्ग पर सभी प्रकार के फ़ंक्शन जेनेरिक में उपयोग किए जा सकते हैं। हालांकि, इसके अलावा, एकमात्र तरीका कक्षाएं बॉयलरप्लेट से बचने में मदद करता है "डिफ़ॉल्ट परिभाषा" की पेशकश करके। अब यहाँ एक अप्रत्याशित सुविधा का एक उदाहरण है!
न्यूनतम बाध्यकारी सेट घोषित / संकलक चेक करने योग्य नहीं हैं। इससे अनजानी परिभाषाएं हो सकती हैं जो पारस्परिक पुनरावृत्ति के कारण नीचे की उपज होती हैं।
महान सुविधा और शक्ति के बावजूद यह उपज देगा, आप अनाथ दोषों को निर्दिष्ट नहीं कर सकते, अनाथ उदाहरणों के कारण http://lukepalmer.wordpress.com/2009/01/25/a-world-without-orphans/ ये हमें ठीक कर देंगे सांख्यिक पदानुक्रम सुशोभित!
THa जैसी क्षमताओं के बाद विधि चूक के लिए जा रहे http://www.haskell.org/haskellwiki/GHC.Generics । हालांकि यह शांत सामान है, इन जेनरिक का उपयोग करने वाला मेरा एकमात्र अनुभव डिबगिंग कोड शून्य-असंभव था, एएसटी के रूप में और एडीटी के लिए प्रेरित प्रकार के आकार के कारण। https://github.com/mgsloan/th-extra/commit/d7784d95d396eb3abdb409a24360beb03731c88c
दूसरे शब्दों में, यह TH द्वारा प्रदान की गई सुविधाओं के बाद चला गया, लेकिन इसे भाषा के एक संपूर्ण डोमेन, निर्माण भाषा को एक प्रकार के सिस्टम प्रतिनिधित्व में उठाना पड़ा। जबकि मैं इसे आपकी सामान्य समस्या के लिए अच्छी तरह से काम करते हुए देख सकता हूं, जटिल लोगों के लिए, यह TH हैकरी की तुलना में कहीं अधिक भयानक प्रतीकों के ढेर से ग्रस्त होने का खतरा है।
TH आपको आउटपुट कोड के मूल्य-स्तरीय संकलन-समय की गणना देता है, जबकि जेनरिक आपको कोड के पैटर्न मिलान / पुनरावृत्ति भाग को टाइप सिस्टम में उठाने के लिए मजबूर करता है। हालांकि यह उपयोगकर्ता को कुछ उपयोगी तरीकों से प्रतिबंधित करता है, मुझे नहीं लगता कि जटिलता इसके लायक है।
मुझे लगता है कि टीएच और लिस्प की तरह मेटाप्रोग्रामिंग की अस्वीकृति ने अधिक लचीले, स्थूल-विस्तार जैसे उदाहरणों की घोषणाओं के बजाय पद्धति-चूक जैसी चीजों को वरीयता दी। उन चीजों से बचने का अनुशासन जो अप्रत्याशित परिणाम पैदा कर सकते हैं, बुद्धिमान हैं, हालांकि, हमें यह ध्यान नहीं देना चाहिए कि हास्केल की सक्षम प्रकार प्रणाली कई अन्य वातावरणों (उत्पन्न कोड की जांच करके) की तुलना में अधिक विश्वसनीय मेटाप्रोग्रामिंग की अनुमति देती है।