एक कार्यात्मक भाषा में संकलक लिखना आसान क्यों है? [बन्द है]


88

मैं इस सवाल पर बहुत लंबे समय से सोच रहा था, लेकिन वास्तव में Google पर जवाब नहीं पा रहा था और साथ ही स्टैकवॉयरफ़्लो पर भी ऐसा ही सवाल था। यदि कोई डुप्लिकेट है, तो मुझे उसके लिए खेद है।

बहुत से लोग यह कहते प्रतीत होते हैं कि संकलक और अन्य भाषा के औजारों को कार्यात्मक भाषाओं जैसे कि ओक्सैमल और हास्केल में लिखना अधिक कुशल और आसान है, फिर उन्हें अनिवार्य भाषाओं में लिखना।

क्या ये सच है? और यदि हां - तो उन्हें सी की तरह एक अनिवार्य भाषा के बजाय कार्यात्मक भाषाओं में लिखना इतना कुशल और आसान क्यों है? इसके अलावा - एक कार्यात्मक भाषा धीमी में भाषा उपकरण नहीं है, तो कुछ निम्न स्तर की भाषा में जैसे C?


5
मैं यह नहीं कहूंगा कि यह आसान है। लेकिन पार्सिंग जैसे कार्यों को संकलित करने की कार्यात्मक प्रकृति शायद खुद को स्वाभाविक रूप से कार्यात्मक प्रोग्रामिंग के लिए उधार देती है। OCaml जैसी कार्यात्मक भाषाएं बहुत तेज हो सकती हैं, C की गति को प्रतिद्वंद्वी कर सकती हैं
रॉबर्ट हार्वे

17
दोस्तों, क्या यह वाकई तर्कपूर्ण है? निश्चित रूप से किसी के पास कुछ अंतर्दृष्टि है। मैं खुद को जानना चाहता हूं।
रॉबर्ट हार्वे

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

12
क्या यह स्वीकार करना वाकई दलील है कि कुछ निचे भाषा की एक विशेष शैली के लिए बेहतर हैं? "डिवाइस ड्राइवरों को लिखने के लिए जावास्क्रिप्ट की तुलना में सी बेहतर क्यों है" विवादास्पद नहीं होगा, मुझे लगता है ...
सीए मैककैन

1
मुझे लगा कि इसके विपरीत होगा। मैं "सुपर नन्हा संकलक" पढ़ रहा हूं और यह सभी जगह चर परिवर्तन का उपयोग करता है।
रॉल्फ

जवाबों:


101

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

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


अब तक के अधिकांश पूर्ण उत्तर, मैं इसे स्वीकृत उत्तर के रूप में चिह्नित करूंगा, लेकिन मुझे लगता है कि पीट किर्कम का उत्तर भी अच्छा है।
wvd

1
"प्रोजोविंग शुद्धता" के बारे में क्या, क्योंकि कंपाइलर की शुद्धता एक महत्वपूर्ण विशेषता है, मैंने अक्सर सुना है कि कार्यात्मक भाषाओं के प्रशंसक किसी भी तरह से अपने वर्कफ़्लो में शुद्धता का "प्रमाण" शामिल करते हैं। मुझे नहीं पता कि व्यावहारिक रूप में इसका क्या मतलब है, लेकिन जैसा कि संकलक विश्वसनीयता महत्वपूर्ण है, यह सार्थक लगता है।
वारेन पी

3
@WarrenP: "प्रूफ-कैरिंग कोड" अवधारणा सांख्यिकीय रूप से टाइप की गई कार्यात्मक भाषाओं से आती है। विचार यह है कि आप टाइप-सिस्टम का उपयोग इस तरह से करते हैं ताकि कोई फ़ंक्शन केवल तभी टाइप करे, जब वह सही हो, इसलिए कोड संकलन सही होने का प्रमाण है। बेशक, यह पूरी तरह से संभव नहीं है, जबकि भाषा को ट्यूरिंग-पूर्ण रखने और निर्णायक टाइप करने के लिए। लेकिन टाइप-सिस्टम जितना मजबूत होगा, आप उस लक्ष्य के जितना करीब होंगे।
sepp2k

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

3
मेरी राय में पैटर्न मिलान एकल सबसे महत्वपूर्ण विशेषता है। पैटर्न मिलान के साथ एक अमूर्त वाक्यविन्यास ट्री का अनुकूलन करना मूर्खतापूर्ण आसान है। पैटर्न के मिलान के बिना ऐसा करना अक्सर निराशाजनक रूप से कठिन होता है।
बॉब अमन

38

बहुत सारे कंपाइलर कार्य पेड़ की संरचनाओं पर पैटर्न से मेल खाते हैं।

OCaml और Haskell दोनों में शक्तिशाली और संक्षिप्त पैटर्न मिलान क्षमताएँ हैं।

अनिवार्य भाषाओं से प्रतिमान जोड़ना अधिक कठिन है क्योंकि जो भी मूल्य-विरोधी मुक्त होना चाहिए उसके प्रति प्रतिमान का मिलान करने के लिए जो भी मूल्यांकन या निकाला जा रहा है।


एक उचित उत्तर की तरह लगता है, लेकिन क्या यह एकमात्र चीज है? उदाहरण के लिए पूंछ पुनरावृत्ति जैसी चीजें भी एक भूमिका निभाएंगी?
wvd

ऐसा प्रतीत होता है कि यह वास्तविक निष्पादन मॉडल की तुलना में प्रकार प्रणाली का एक मुद्दा है। संरचनात्मक प्रकारों पर अपरिवर्तनीय मूल्यों के साथ अनिवार्य प्रोग्रामिंग पर आधारित कुछ ठीक हो सकता है।
डोनल फेलो

@ wvd: टेल रिकर्सियन ऑप्टिमाइज़ेशन एक कार्यान्वयन विवरण है, न कि एक भाषा सुविधा, जैसे कि रैखिक पुनरावर्ती कार्यों को पुनरावृत्त लूप के बराबर बनाता है। C में लिंक की गई सूची को चलाने के लिए एक पुनरावर्ती कार्य से उसे उतना ही लाभ होगा, जितना स्कीम में किसी सूची पर पुनरावृत्ति करने से होता है।
सीए मैक्कैन

@ wvd gcc C में टेल कॉल एलिमिनेशन है, जैसा कि अन्य उत्परिवर्ती राज्य भाषाएं करते हैं
पीट किर्कम

3
@camccann: यदि भाषा मानक tco की गारंटी देता है (या कम से कम गारंटी देता है कि एक निश्चित रूप के पुनरावर्ती कार्य कभी भी स्टैक ओवरफ्लो या मेमोरी खपत के रैखिक विकास का कारण नहीं बनेंगे), तो मुझे लगता है कि एक भाषा सुविधा होगी। यदि मानक इसकी गारंटी नहीं देता है, लेकिन संकलक इसे वैसे भी करता है, तो यह एक संकलक सुविधा है।
sepp2k

15

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

मेरे आखिरी कंपाइलर-एस्क जॉब में हमने सी कोड में हेरफेर करते हुए ठीक इसी वजह से OCaml का इस्तेमाल किया, यह टास्क के लिए सिर्फ सबसे अच्छा टूल था। अगर INRIA के लोगों ने OCaml को अलग-अलग प्राथमिकताओं के साथ बनाया था तो यह इतना अच्छा फिट नहीं हो सकता था।

उन्होंने कहा, कार्यात्मक भाषाएं किसी भी समस्या को हल करने के लिए सबसे अच्छा उपकरण हैं, इसलिए यह तार्किक रूप से इस प्रकार है कि वे इस विशेष समस्या को हल करने के लिए सबसे अच्छा उपकरण हैं। QED।

/ मुझे: मेरे जावा कार्यों को थोड़ा कम खुशी से क्रॉल करता है ...


4
-1 के लिए "कार्यात्मक भाषा किसी भी समस्या को हल करने के लिए सबसे अच्छा उपकरण है।" अगर यह सच होता, तो हम सभी हर जगह उनका इस्तेमाल करते। ;)
आंद्रेई क्रोटकोव

15
@Andrei क्रोटकोव: दिन का शब्द शब्द है fa · ce · tious उच्चारण: \ fə-əsə-shˈs \ समारोह: विशेषण व्युत्पत्ति विज्ञान: मध्य फ्रेंच facetieux, facetie jest से, लैटिन facetia से दिनांक: 1599 1: मजाक या मजाक में अक्सर अनुचित तरीके से मजाक करना। : waggish <just facetious> 2: का मतलब हास्य या मजाकिया होना है: गंभीर नहीं गंभीर टिप्पणी करना। समानार्थी शब्द मजाकिया देखें मजाक में लापता होने के शीर्ष पर, आपका तर्क अभी भी त्रुटिपूर्ण है। आप यह मान रहे हैं कि सभी लोग तर्कसंगत अभिनेता हैं, और इससे मैं डरता हूं, यह उचित धारणा नहीं है।
उक्को

5
मुझे लगता है कि मैंने मजाक को याद किया, जैसा कि मैं वास्तविक जीवन में लोगों को जानता हूं कि पूरी तरह से गंभीरता से छोड़कर, बहुत सटीक बात कहेंगे। पो का नियम मुझे लगता है। tvtropes.org/pmwiki/pmwiki.php/Main/PoesLaw
आंद्रेई

13
@Andrei: अपने डिबग विज्ञापन ad populum का उपयोग करना : "यदि कारण भावनात्मक अज्ञानता से बेहतर है, तो हम सभी इसका हर जगह उपयोग करेंगे।"
टिम शेफ़र

9

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


6

यह सभी देखें

एफ # डिजाइन पैटर्न

FP समूह चीजों को 'ऑपरेशन द्वारा' करता है, जबकि OO समूह चीजों को 'टाइप', और 'ऑपरेशन द्वारा' एक संकलक / दुभाषिया के लिए अधिक स्वाभाविक है।


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

6

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


4

लगता है जैसे हर कोई एक और महत्वपूर्ण कारण चूक गया। पार्सर्स के लिए एक एम्बेडेड डोमेन विशिष्ट भाषा (EDSL) लिखना काफी आसान है जो सामान्य कोड में बहुत कुछ (E) BNF जैसा दिखता है। पार्सर कॉम्बिनेटर जैसे उच्च-क्रम के कार्यों और फ़ंक्शन संरचना का उपयोग करके कार्यात्मक भाषाओं में लिखना काफी आसान है। न केवल आसान बल्कि बहुत ही शान से।

मूल रूप से आप केवल कार्यों के रूप में सबसे सरल जेनेरिक पार्सर का प्रतिनिधित्व करते हैं और आपके पास विशेष ऑपरेशन (आमतौर पर उच्च-क्रम वाले कार्य) होते हैं, जो आपको इन व्याकरणिक पार्सर को अपने व्याकरण के लिए अधिक जटिल, अधिक विशिष्ट पार्सर में रचना करने देते हैं ।

यह पाठ्यक्रम के समांतर ढांचे को करने का एकमात्र तरीका नहीं है।

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