एक प्रोग्रामिंग भाषा के कौन से गुण संकलन को असंभव बनाते हैं?


71

सवाल:

"एक प्रोग्रामिंग भाषा के कुछ गुणों की आवश्यकता हो सकती है कि इसमें लिखा कोड प्राप्त करने का एकमात्र तरीका व्याख्या द्वारा है। दूसरे शब्दों में, पारंपरिक सीपीयू के एक देशी मशीन कोड का संकलन संभव नहीं है। ये गुण क्या हैं?"

कंपाइलर: पराग एच। दवे और हिमांशु बी। दवे (2 मई, 2012) के सिद्धांत और अभ्यास

पुस्तक उत्तर के बारे में कोई सुराग नहीं देती है। मैंने कॉन्सेप्ट ऑफ़ प्रोग्रामिंग लैंग्वेज (SEBESTA) पर जवाब खोजने की कोशिश की, लेकिन कोई फायदा नहीं हुआ। वेब खोजों का बहुत कम लाभ था। क्या आपके पास कोई सुराग है?


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

4
@ राफेल: अच्छा विचार है, लेकिन ... 1) आप मान रहे हैं कि कोड निष्पादित होने से पहले उपलब्ध है। यह इंटरैक्टिव उपयोग के लिए पकड़ नहीं है। निश्चित रूप से, आप बस स्टेट-इन कॉम्पीटिशन का उपयोग देशी कोड को बैश स्टेटमेंट या पोस्टस्क्रिप्ट स्टैक सामग्री पर कर सकते हैं, लेकिन यह एक बहुत ही पागल विचार है। 2) आपका विचार वास्तव में कोड को संकलित नहीं करता है: बंडल कोड का संकलित संस्करण नहीं है, लेकिन फिर भी कोड के लिए एक दुभाषिया है।
रीइंजिएरपोस्ट 16

7
अच्छे पुराने दिनों में मेरे पास आत्म संपादन gwbasic प्रोग्राम थे (gwbasic store एक तरह के bytecode में बुनियादी कार्यक्रम)। वर्तमान में मैं खुद को संपादित करने की अपनी क्षमता को बनाए रखते हुए देशी मशीन कोड को संकलित करने के लिए एक समझदार तरीके के बारे में नहीं सोच सकता।
प्लाज़्माएचएच

15
@PlasmaHH: सेल्फ मॉडिफाइंग कोड 1948 तक चला जाता है। पहला कंपाइलर 1952 में लिखा गया था। स्व-संशोधित कोड की अवधारणा देशी मशीन कोड में ईजाद की गई थी ।
मूविंग डक

10
@reinierpost राफेल इस मुद्दे पर एक सैद्धांतिक रुख ले रहा है। इसमें प्रश्न की वैचारिक सीमाओं को दिखाने का गुण है। संकलन का अनुवाद भाषा S से भाषा में होता है। T से भाषा T का विस्तार हो सकता है, जिसमें कुछ अन्य अपक्षय में कोड की व्याख्या की जा सकती है। इसलिए S और उसके दुभाषिए को बांधना भाषा T में एक कार्यक्रम है। यह एक इंजीनियर के लिए बेतुका लगता है, लेकिन यह दर्शाता है कि प्रश्न को सार्थक रूप से तैयार करना आसान नहीं है। आप इंजीनियरिंग के दृष्टिकोण से एक अस्वीकार्य एक (जैसे राफेल के) से एक स्वीकार्य संकलन प्रक्रिया को कैसे भेद करते हैं?
बबौ

जवाबों:


61

व्याख्या और संकलित कोड के बीच का अंतर शायद एक कल्पना है, जैसा कि राफेल की टिप्पणी से रेखांकित किया गया है :

the claim seems to be trivially wrong without further assumptions: if there is
an interpreter, I can always bundle interpreter and code in one executable ...

तथ्य यह है कि कोड की व्याख्या हमेशा सॉफ़्टवेयर द्वारा, हार्डवेयर या दोनों के संयोजन से की जाती है, और संकलन प्रक्रिया यह नहीं बता सकती है कि यह कौन सा होगा।

संकलन के रूप में आप जो अनुभव करते हैं वह एक भाषा (स्रोत के लिए) से दूसरी भाषा (लक्ष्य के लिए) के लिए एक अनुवाद प्रक्रिया है । और, लिए दुभाषिया आमतौर पर लिए दुभाषिया से अलग होता है ।STST

संकलित कार्यक्रम का अनुवाद एक वाक्य-रचना रूप से दूसरे वाक्य- रूप , जैसे कि, और , और भाषाओं के को देखते हुए समान कम्प्यूटेशनल व्यवहार है, जो आमतौर पर आप कुछ करने की कोशिश कर रहे हैं परिवर्तन, संभवतः अनुकूलन करने के लिए, जैसे कि जटिलता या सरल दक्षता (समय, स्थान, सतह, ऊर्जा की खपत)। मैं कार्यात्मक तुल्यता की बात नहीं करने की कोशिश कर रहा हूं, क्योंकि इसके लिए सटीक परिभाषाओं की आवश्यकता होगी।P T T S T P S P TPSPTSTPSPT

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

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

एक बात जो समस्या खड़ी कर सकती है, वह है, मेटा-सर्कुलरिटी । ऐसा तब होता है जब कोई प्रोग्राम अपनी स्रोत भाषा में वाक्य रचनाओं में हेरफेर करेगा , जिससे प्रोग्राम के टुकड़े पैदा होंगे जो कि उस समय के रूप में जैसे कि वे मूल कार्यक्रम का हिस्सा थे। चूँकि आप भाषा में मनमाने ढंग से प्रोग्राम के टुकड़े पैदा कर सकते हैं , अर्थहीन वाक्य-विन्यास के टुकड़ों में हेरफेर करने के परिणामस्वरूप मनमाने ढंग से गणना करने के परिणामस्वरूप, मुझे लगता है कि आप इस प्रोग्राम को भाषा में संकलित करने के लिए लगभग असंभव (इंजीनियरिंग के दृष्टिकोण से) बना सकते हैं , ताकि यह अब टुकड़े उत्पन्न करता है । इसलिए के लिए दुभाषिया की आवश्यकता होगी, या कम से कम संकलक के लिएS T T S S S T SSSTTSST के लिए ऑन-द-मक्खी संकलन में उत्पन्न टुकड़ों के (यह भी देखें इस दस्तावेज़ )।S

लेकिन मुझे यकीन नहीं है कि इसे कैसे ठीक से औपचारिक रूप दिया जा सकता है (और इसके लिए अभी समय नहीं है)। और असंभव एक ऐसे मुद्दे के लिए एक बड़ा शब्द है जो औपचारिक नहीं है।

फखर की टिप्पणी

36 घंटे के बाद जोड़ा गया। आप इसे बहुत लंबी अगली कड़ी छोड़ सकते हैं।

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

व्याख्या और संकलन को देखने के कई तरीके हैं, और मैं कुछ हद तक स्केच करने की कोशिश करूंगा। मैं प्रबंधन करने के लिए अनौपचारिक होने का प्रयास करूंगा

टॉम्बस्टोन आरेख

प्रारंभिक औपचारिकरण में से एक (1960 के दशक के अंत से 1990 तक) टी या समाधि का चित्र है । इन आरेखों ने रचनाकार आलेखीय तत्वों को दुभाषिया या संकलक की कार्यान्वयन भाषा, स्रोत भाषा की व्याख्या या संकलित की जा रही भाषा, और संकलक के मामले में लक्ष्य भाषा प्रस्तुत की। अधिक विस्तृत संस्करण विशेषताएँ जोड़ सकते हैं। इन ग्राफिक अभ्यावेदन को स्वयंसिद्ध, अनुमान नियमों के रूप में देखा जा सकता है, जो स्वयंसिद्ध रूप से व्युत्पन्न प्रोसेसर पीढ़ी से स्वयंसिद्ध, अ ला करी-हावर्ड (हालांकि मुझे यकीन नहीं है कि छठे दशक में किया गया था) से अस्तित्व में आने के योग्य है।

आंशिक मूल्यांकन

एक और दिलचस्प दृश्य आंशिक मूल्यांकन प्रतिमान है। मैं एक प्रकार के फ़ंक्शन कार्यान्वयन के रूप में कार्यक्रमों का एक सरल दृष्टिकोण ले रहा हूं, जो कुछ इनपुट डेटा दिए गए उत्तर की गणना करता है। फिर भाषा के लिए एक दुभाषिया एक प्रोग्राम है जो में लिखा गया प्रोग्राम है और उस प्रोग्राम के लिए डेटा , और के शब्दार्थ के अनुसार परिणाम की गणना करता है । आंशिक मूल्यांकन दो तर्कों और कार्यक्रम की विशेषज्ञता के लिए एक तकनीक है , जब केवल एक तर्क, , को जाना जाता है। जब आप अंततः दूसरा तर्क प्राप्त करते हैं तो इरादे का तेज़ मूल्यांकन होता है एस पी एस एस डी एस एक 1 एक 2 एक 1 एक 2ISSpSSdSa1a2a1a2 । यह विशेष रूप से उपयोगी है यदि से अधिक बार क्योंकि साथ आंशिक मूल्यांकन की लागत को उन सभी पर परिशोधन किया जा सकता है जहां केवल बदल रहा है।a2a1a1a2

एल्गोरिथ्म डिज़ाइन में यह अक्सर स्थिति होती है (अक्सर एसई-सीएस पर पहली टिप्पणी का विषय), जब डेटा का कुछ और स्थिर भाग पूर्व-संसाधित होता है, ताकि सभी अनुप्रयोगों पर पूर्व-प्रसंस्करण की लागत को बढ़ाया जा सके एल्गोरिथ्म इनपुट डेटा के अधिक चर भागों के साथ।

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

स्मन प्रमेय

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

एक गोडेल नंबर को देखते हुए पुनरावर्ती कार्यों की, तो आप देख सकते हैं अपने हार्डवेयर के रूप में है, ताकि गोडेल संख्या को देखते हुए (पढ़ वस्तु कोड ) एक कार्यक्रम के समारोह द्वारा परिभाषित किया गया (यानी वस्तु कोड द्वारा पर अभिकलन आपका हार्डवेयर)।φφpφpp

अपने सरलतम रूप में, प्रमेय को विकिपीडिया में निम्नानुसार बताया गया है (संकेतन में एक छोटे से परिवर्तन तक):

पुनरावर्ती कार्यों की एक Gödel नंबरिंग को देखते हुए , निम्नलिखित संपत्ति के साथ दो तर्कों का एक आदिम पुनरावर्ती फ़ंक्शन है: प्रत्येक Gödel संख्या के लिए आंशिक तर्कपूर्ण फ़ंक्शन के लिए दो तर्क, अभिव्यक्ति और को प्राकृतिक संख्याओं और के समान संयोजनों के लिए परिभाषित किया गया है , और ऐसे किसी भी संयोजन के लिए उनके मूल्य समान हैं। दूसरे शब्दों में, फ़ंक्शंस की निम्न आयामी समानता हर : φσqfφσ(q,x)(y)f(x,y)xyxφσ(q,x)λy.φq(x,y).

अब, लेने दुभाषिए के रूप में , एक कार्यक्रम के स्रोत कोड के रूप में , और के रूप में डेटा है कि कार्यक्रम के लिए, हम लिख सकते हैं: qISxpSydφσ(IS,pS)λd.φIS(pS,d).

φIS को हार्डवेयर पर दुभाषिया के निष्पादन के रूप में देखा जा सकता है , अर्थात, भाषा में लिखे गए कार्यक्रमों की व्याख्या करने के लिए एक ब्लैक-बॉक्स तैयार है ।ISS

फ़ंक्शन को एक फ़ंक्शन के रूप में देखा जा सकता है जो आंशिक मूल्यांकन में प्रोग्राम लिए दुभाषिया को माहिर करता है । इस प्रकार Gödel संख्या देखी जा सकती है जिसमें ऑब्जेक्ट कोड है जो प्रोग्राम का संकलित संस्करण है ।σISPSσ(IS,pS)pS

तो फ़ंक्शन को एक फ़ंक्शन के रूप में देखा जा सकता है , जो भाषा में लिखे प्रोग्राम के स्रोत कोड को तर्क के रूप में लेते हैं , और उस प्रोग्राम के लिए ऑब्जेक्ट कोड संस्करण वापस करते हैं। तो वह है जिसे आमतौर पर कंपाइलर कहा जाता है।CS=λqS.σ((IS,qS)qSSCS

कुछ निष्कर्ष

हालाँकि, जैसा कि मैंने कहा: "सिद्धांत एक झूठा हो सकता है", या वास्तव में एक प्रतीत होता है। समस्या यह है कि हम फ़ंक्शन का कुछ भी नहीं जानते हैं । वास्तव में ऐसे कई कार्य हैं, और मेरा अनुमान है कि प्रमेय का प्रमाण इसके लिए एक बहुत ही सरल परिभाषा का उपयोग कर सकता है, जो इंजीनियरिंग के दृष्टिकोण से, राफेल द्वारा प्रस्तावित समाधान की तुलना में बेहतर नहीं हो सकता है: बस सीधे बंडल करने के लिए स्रोत कोड दुभाषिया । यह हमेशा किया जा सकता है, ताकि हम कह सकें: संकलन हमेशा संभव है।क्ष एस मैं एसσqSIS

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

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

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

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

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

ध्यान दें कि संकलन प्रक्रिया को मशीन कोड का उत्पादन करना चाहिए कोई मदद नहीं है। यह ठीक है कि बंडलिंग क्या कर सकता है क्योंकि दुभाषिया मशीन कोड है (ठीक है, क्रॉस-कंपार्टमेंट के साथ चीज़ थोड़ी अधिक जटिल हो सकती है)।


3
" असंभव एक बड़ा शब्द है" एक बहुत बड़ा शब्द। =)
ब्रायन एस

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

@ ब्रायन नहीं, यह नहीं है, और अन्यथा यह साबित करना असंभव है;)
माइकल गाज़ोन्डा

@supercat अभी भी एक परिभाषा नहीं है। भाषा निर्माण का 'अर्थ ’क्या है?
राइमॉइड

मुझे संकलक / दुभाषिया को आंशिक निष्पादन के रूप में देखने की अवधारणा पसंद है!
बरगी

17

प्रश्न वास्तव में संकलन असंभव होने के बारे में नहीं है । यदि किसी भाषा की व्याख्या की जा सकती है, तो उसे दुभाषिया तरीके से संकलित किया जा सकता है, दुभाषिया को स्रोत कोड के साथ बंडल करके। सवाल यह पूछ रहा है कि कौन सी भाषा सुविधाएँ इसे अनिवार्य रूप से एकमात्र तरीका बनाती हैं।

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

सिर्फ इसलिए कि एक भाषा में evalइसका मतलब यह नहीं है कि इसका थोक मूल कोड में संकलित नहीं किया जा सकता है। उदाहरण के लिए, लिस्प संकलक का अनुकूलन कर रहे हैं, जो अच्छे देशी कोड उत्पन्न करते हैं, और फिर भी वे समर्थन करते हैं eval; eval'एड कोड की व्याख्या हो सकती है, या मक्खी पर संकलित की जा सकती है।

evalअंतिम जरूरत-ए-दुभाषिया विशेषता है, लेकिन ऐसी अन्य विशेषताएं हैं जिनके लिए दुभाषिया की कुछ कमी की आवश्यकता होती है। संकलक के कुछ विशिष्ट चरणों पर विचार करें:

  1. पदच्छेद
  2. प्रकार की जाँच
  3. कोड पीढ़ी
  4. लिंक करना

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

सामान्यतया, परावर्तन देशी कोड को संकलित करने के लिए भाषाओं को कठिन बनाता है। एक स्पष्ट आदिम प्रतिबिंब का एक चरम मामला है; कई भाषाएं अब तक नहीं चली हैं, लेकिन फिर भी एक वर्चुअल मशीन के संदर्भ में एक शब्दार्थ को परिभाषित किया गया है, उदाहरण के लिए कोड को नाम से एक वर्ग प्राप्त करने की अनुमति देता है, इसकी विरासत का निरीक्षण करता है, इसके तरीकों को सूचीबद्ध करता है, एक विधि को कॉल करता है, आदि जावा जेवीएम के साथ। और .NET के साथ C # दो प्रसिद्ध उदाहरण हैं। इन भाषाओं को लागू करने का सबसे सीधा तरीका यह है कि उन्हें बायटेकोड पर संकलित किया जाए , लेकिन फिर भी देशी कंपाइलर (कई जस्ट-इन-टाइम ) हैं जो कम से कम प्रोग्राम अंशों को संकलित करते हैं जो उन्नत प्रतिबिंब सुविधाओं का उपयोग नहीं करते हैं।

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

A व्यायाम: एक ऐसी भाषा को परिभाषित करें जिसे व्याख्यायित नहीं किया जा सकता है।


(१) मैं एक दुभाषिया को संकलन के रूप में स्रोत कोड की गिनती के साथ जोड़ने के बारे में असहमत हूं, लेकिन आपकी बाकी पोस्ट उत्कृष्ट है। (२) टोटल एवल के बारे में सहमत होना। (३) मैं यह नहीं देखता कि परावर्तन देशी भाषाओं को संकलित करने के लिए कठिन क्यों होगा। उद्देश्य-सी में प्रतिबिंब है, और (मुझे लगता है) यह आमतौर पर संकलित है। (4) अस्पष्ट रूप से संबंधित नोट, C ++ टेम्प्लेट मेटामैजिक को आमतौर पर संकलित किए जाने के बजाय समझा जाता है।
मूविंग डक

बस मेरे लिए, लुआ संकलित है। evalबस बाईटकोड संकलित, और फिर एक अलग कदम के रूप में द्विआधारी बाईटकोड निष्पादित करता है। और यह निश्चित रूप से संकलित बाइनरी में प्रतिबिंब है।
मूविंग डक

हार्वर्ड आर्किटेक्चर मशीन पर, संकलन को कोड प्राप्त करना चाहिए जिसे कभी भी "डेटा" के रूप में एक्सेस नहीं करना पड़ता है। मैं स्रोत फ़ाइल से उस जानकारी को प्रस्तुत करता हूं जो कोड के बजाय डेटा के रूप में संग्रहीत होने के लिए समाप्त होता है, वास्तव में "संकलित" नहीं है। एक संकलक के साथ घोषणा करने में कुछ भी गलत नहीं है जैसे कि int arr[] = {1,2,5};[1,2,5] युक्त एक इनिशियलाइज़्ड-डेटा सेक्शन उत्पन्न करता है, लेकिन मैं इसके व्यवहार को मशीन कोड में [1,2,5] के रूप में अनुवाद करने का वर्णन नहीं करूँगा। यदि प्रोग्राम के लगभग सभी को डेटा के रूप में संग्रहीत किया जाना है, तो इसका कौन सा भाग वास्तव में "संकलित" होगा?
23

2
@ सुपरकैट वह है जो गणितज्ञ और कंप्यूटर वैज्ञानिक तुच्छ से मतलब रखते हैं। यह गणितीय परिभाषा में फिट बैठता है, लेकिन कुछ भी दिलचस्प नहीं होता है।
गाइल्स

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

13

मुझे लगता है कि लेखक मान रहे हैं कि संकलन का मतलब है

  • स्रोत कार्यक्रम को रन-टाइम पर मौजूद होने की आवश्यकता नहीं है, और
  • कोई संकलक या दुभाषिया को रन-टाइम पर उपस्थित होने की आवश्यकता नहीं है।

यहां कुछ नमूना विशेषताएं दी गई हैं जो इस तरह की योजना के लिए "असंभव" नहीं होने पर इसे समस्याग्रस्त बना देगा:

  1. यदि आप किसी चर के मान को रन-टाइम पर, उसके नाम (जो एक स्ट्रिंग है) द्वारा चर का उल्लेख करके पूछताछ कर सकते हैं, तो आपको चर नामों को चलाने के समय के आसपास होने की आवश्यकता होगी।

  2. यदि आप रन-टाइम पर किसी फ़ंक्शन / प्रक्रिया को उसके नाम (जिसे एक स्ट्रिंग है) द्वारा संदर्भित करके कॉल कर सकते हैं, तो आपको रन-टाइम पर फ़ंक्शन / प्रक्रिया के नामों की आवश्यकता होगी।

  3. यदि आप रन-टाइम (एक स्ट्रिंग के रूप में) पर एक कार्यक्रम का निर्माण कर सकते हैं, तो किसी अन्य प्रोग्राम को चलाकर, या इसे एक नेटवर्क कनेक्शन आदि से पढ़कर कह सकते हैं, तो आपको रन-टाइम पर एक दुभाषिया या एक कंपाइलर की आवश्यकता होगी कार्यक्रम के इस टुकड़े को चलाएं।

लिस्प में तीनों विशेषताएं हैं। इसलिए, लिस्प प्रणालियों में हमेशा एक दुभाषिया होता है जो रन-टाइम पर लोड होता है। भाषा जावा और C # में फ़ंक्शन नाम रन टाइम पर उपलब्ध हैं, और टेबल पर देखने के लिए कि उनका क्या मतलब है। संभवत: बेसिक और पायथन जैसी भाषाओं में भी रन टाइम में परिवर्तनशील नाम होते हैं। (मैं उस बारे में 100% निश्चित नहीं हूं)।


क्या होगा अगर "दुभाषिया" कोड में संकलित किया जाता है? उदाहरण के लिए, आभासी विधियों को कॉल करने के लिए प्रेषण तालिकाओं का उपयोग करना, क्या ये व्याख्या या संकलन का उदाहरण हैं?
इरविन बोलविडेट

2
"कोई संकलक या दुभाषिया को रन-टाइम में उपस्थित होने की आवश्यकता नहीं है", एह? अगर यह सच है, तो एक गहरे अर्थ में, C को अधिकांश प्लेटफार्मों पर "संकलित" नहीं किया जा सकता है। सी रनटाइम के लिए बहुत कुछ नहीं है: स्टार्टअप, ढेर और आगे स्थापित करने के लिए, और atexitप्रसंस्करण के लिए शटडाउन । लेकिन यह अभी भी वहाँ है।
छद्म नाम

1
"लिस्प सिस्टम में हमेशा एक दुभाषिया होता है जो रन-टाइम पर लोड होता है।" - जरुरी नहीं। कई लिस्प प्रणालियों में एक संकलक होता है। कुछ भी एक दुभाषिया बिल्कुल भी नहीं है।
जोर्ग डब्ल्यू मित्तग

2
अच्छी कोशिश, लेकिन en.wikipedia.org/wiki/Lisp_machine#Technical_overview । वे लिस्प संकलित करते हैं और परिणाम को कुशलतापूर्वक निष्पादित करने के लिए डिज़ाइन किए गए हैं।
पीटर ए। श्नाइडर

@Pseudonym: C रनटाइम एक लाइब्रेरी है, न कि कंपाइलर और न ही दुभाषिया।
मूविंग डक

8

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

अन्य उत्तर बताते हैं कि संकलित बनाम संकलित भाषाओं के अंतर कई मामलों में महत्वपूर्ण रूप से धुंधला हो सकते हैं जैसे कि अधिक आधुनिक भाषाओं में जावा को "सिर्फ समय संकलक" उर्फ "हॉटस्पॉट" (जावास्क्रिप्ट इंजन जैसे वी 8 ने इसी तकनीक को तेजी से बढ़ाया)। "eval-like" कार्यक्षमता निश्चित रूप से उनमें से एक है।


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

1
लुआ वही काम करता है।
मूविंग डक

3

LISP एक भयानक उदाहरण है, क्योंकि इसे "वास्तविक" भाषा के लिए आधार के रूप में उच्च-स्तरीय "मशीन" भाषा के रूप में कल्पना की गई थी। कहा "वास्तविक" भाषा कभी भौतिक नहीं हुई। LISP मशीनों को हार्डवेयर में (बहुत) LISP करने के विचार पर बनाया गया था। चूंकि LISP दुभाषिया सिर्फ एक कार्यक्रम है, इसलिए इसे सर्किटरी में लागू करना सिद्धांत रूप में संभव है। व्यावहारिक नहीं, शायद; लेकिन असंभव से बहुत दूर।

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

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

दूसरी ओर, आधुनिक सीपीयू भी "मशीन भाषा" इनपुट लेते हैं और इसे निचले-स्तर के निर्देशों में अनुवाद करते हैं, जिन्हें फिर से निष्पादित करने के लिए सौंप दिए जाने से पहले फिर से व्यवस्थित और अनुकूलित (यानी, "संकलित") किया जाता है।

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


1

वास्तविकता यह है कि कुछ बेसिक प्रोग्राम की व्याख्या करने और कोडांतरक को निष्पादित करने के बीच एक बड़ा अंतर है। और पी-कोड / बाइट-कोड के साथ या बिना (सिर्फ-इन-टाइम) संकलक के बीच के क्षेत्र हैं। इसलिए मैं इस वास्तविकता के संदर्भ में कुछ बिंदुओं को संक्षेप में बताने का प्रयास करूंगा।

  • यदि स्रोत कोड को पार्स किया जाता है तो रन-टाइम परिस्थितियों पर निर्भर करता है, संकलक लिखना असंभव हो सकता है, या इतना कठिन कि कोई भी परेशान नहीं करेगा।

  • कोड जो खुद को संशोधित करता है वह सामान्य मामले में संकलन करना असंभव है।

  • एक प्रोग्राम जो एक eval-like फ़ंक्शन का उपयोग करता है, आमतौर पर पहले से पूरी तरह से संकलित नहीं किया जा सकता है (यदि आप इसे प्रोग्राम के हिस्से के रूप में इसे दिए गए स्ट्रिंग के संबंध में मानते हैं), हालांकि यदि आप eval'ed कोड को बार-बार चलाने जा रहे हैं तो यह अभी भी हो सकता है आपके eval-like फंक्शन को संकलित करने के लिए उपयोगी है। कुछ भाषाएँ कंपाइलर को यह आसान बनाने के लिए एक एपीआई प्रदान करती हैं।

  • नाम से चीजों को संदर्भित करने की क्षमता संकलन को रोकता नहीं है, लेकिन आपको तालिकाओं की आवश्यकता है (जैसा कि उल्लेख किया गया है)। नाम से कार्यों को कॉल करना (जैसे IDispatch) को बहुत सी पाइपलाइन की आवश्यकता होती है, इस बिंदु पर जहां मुझे लगता है कि अधिकांश लोग सहमत होंगे कि हम प्रभावी रूप से एक फ़ंक्शन कॉल दुभाषिया के बारे में बात कर रहे हैं।

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


1

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

दूसरे शब्दों में भाषा अपनी स्वयं की मेटा-प्रणाली का प्रतिनिधित्व कर सकती है ( मेटाप्रोग्रामिंग भी देखें )

ध्यान दें कि भाषा प्रतिबिंब , एक निश्चित स्रोत कोड के मेटा-डेटा के बारे में क्वेरी करने के अर्थ में, और संभवतः मेटा-डेटा को केवल संशोधित करता है, (जावा या PHP के प्रतिबिंब तंत्र की तरह sth) एक संकलक के लिए समस्याग्रस्त नहीं है , क्योंकि यह पहले से ही है। संकलन समय पर मेटा-डेटा और जरूरत पड़ने पर उन्हें संकलित कार्यक्रम को उपलब्ध करा सकता है।

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


LISP एक भयानक उदाहरण है, क्योंकि यह एक स्पार्ट के रूप में गर्भ धारण कर रहा था
vonbrand

@vonbrand, हो सकता है लेकिन दोनों समरूपता अवधारणा और एक समान डेटा-कोड द्वैत प्रदर्शित करता है
निकोस एम।

-1

मुझे लगता है कि मूल प्रश्न ठीक से नहीं बना है। प्रश्न के लेखकों ने कुछ अलग सवाल पूछने का इरादा किया हो सकता है: एक प्रेरक भाषा के कौन से गुण इसके लिए एक कंपाइलर लिखने की सुविधा प्रदान करते हैं?

उदाहरण के लिए, संदर्भ-संवेदनशील भाषा की तुलना में संदर्भ-मुक्त भाषा के लिए संकलक लिखना आसान है। एक भाषा को परिभाषित करने वाले व्याकरण में ऐसे मुद्दे भी हो सकते हैं जो इसे संकलन करने के लिए चुनौतीपूर्ण बनाते हैं, जैसे कि अस्पष्टता। इस तरह के मुद्दों को हल किया जा सकता है लेकिन अतिरिक्त प्रयास की आवश्यकता होती है। इसी तरह, अप्रतिबंधित व्याकरण द्वारा परिभाषित भाषाएं संदर्भ-संवेदनशील भाषाओं की तुलना में अधिक कठिन हैं (देखें चॉम्स्की हायरार्की )। मेरे ज्ञान के लिए सबसे व्यापक रूप से इस्तेमाल की जाने वाली प्रक्रियात्मक प्रोग्रामिंग भाषाएं संदर्भ-मुक्त हैं, लेकिन कुछ संदर्भ-संवेदनशील तत्व हैं, जिससे उन्हें संकलन करना अपेक्षाकृत आसान है।


2
सवाल स्पष्ट रूप से संकलनकर्ताओं और दुभाषियों का विरोध / तुलना करने का इरादा है। हालांकि वे अलग तरीके से काम कर सकते हैं, और आमतौर पर ऊपर @Raphael सीमा मामले को छोड़कर, वे वाक्यविन्यास विश्लेषण और अस्पष्टता के बारे में बिल्कुल समान समस्याएं हैं। तो वाक्यविन्यास मुद्दा नहीं हो सकता। मेरा यह भी मानना ​​है कि संकलक समस्या आजकल संकलक लेखन में प्रमुख चिंता का विषय नहीं है, हालांकि यह अतीत में रहा है। मैं नीच नहीं हूं: मैं टिप्पणी करना पसंद करता हूं।
बबौ

-1

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

यदि आप अभी तक स्रोत कोड नहीं रखते हैं, तो मशीन कोड में स्रोत कोड का संकलन असंभव है

दुभाषिए लचीलापन जोड़ते हैं, और विशेष रूप से वे चलने वाले कोड के लचीलेपन को जोड़ते हैं जो अंतर्निहित परियोजना संकलित होने पर उपलब्ध नहीं था।


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

1
@DavidRicherby मुझे लगता है कि दिमाग में उपयोग केस टायलेरी इंटरेक्टिव व्याख्या है, यानी रनटाइम में दर्ज किया गया कोड। मैं सहमत हूं, हालांकि, यह सवाल के दायरे से बाहर है क्योंकि यह भाषा की विशेषता नहीं है।
राफेल

@ डैविडरिचर्बी और राफेल, मैं कहता हूं कि इस पोस्ट के लेखक का अर्थ है (मैं अपने उत्तर में क्या वर्णन करता हूं) के रूप में स्व-संशोधन सुविधा जो निश्चित रूप से डिजाइन द्वारा एक भाषा का निर्माण है और कुछ विशिष्ट कार्यक्रम की कलाकृति नहीं है
निकोन्स एम।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.