क्या वास्तव में मेटाप्रोग्रामिंग है?


128

मैं जावा प्लेटफ़ॉर्म पर ployglot प्रोग्रामिंग पर TheServerSide पर एक लेख पढ़ रहा था । लेख में कुछ टिप्पणियां कोड उत्पन्न करने की क्षमता (शायद मक्खी पर) के रूप में मेटाप्रोग्रामिंग का उल्लेख करती हैं।

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


7
आपको इस उत्तर में रुचि हो सकती है stackoverflow.com/questions/2565572/…
ewernli

@ewernli: यह उत्तर वास्तव में यहाँ के किसी भी उत्तर से बेहतर है!
जेडी

जवाबों:


100

मेटाप्रोग्रामिंग से तात्पर्य कई प्रकार से होता है, जिसमें किसी प्रोग्राम का स्वयं का ज्ञान होता है या खुद को हेरफेर कर सकता है।

C # जैसी भाषाओं में, प्रतिबिंब मेटाप्रोग्रामिंग का एक रूप है क्योंकि कार्यक्रम स्वयं के बारे में जानकारी की जांच कर सकता है। उदाहरण के लिए किसी वस्तु के सभी गुणों की सूची वापस करना।

ActionScript जैसी भाषाओं में, आप नए प्रोग्राम जैसे कि eval ("x" + i) बनाने के लिए रनटाइम पर फ़ंक्शन का मूल्यांकन कर सकते हैं। DoSomething () एक वस्तु को प्रभावित करेगा जिसे X1 कहा जाता है जब मैं 1 और x2 होता है जब मैं 2 होता हूं।

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

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

पॉल ग्राहम के निबंध "व्हाट मेड लिस्प डिफरेंट" से :

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

लिस्प कोड लिस्प डेटा ऑब्जेक्ट्स से बना है। और न कि तुच्छ अर्थों में कि स्रोत फ़ाइलों में वर्ण होते हैं, और तार भाषा द्वारा समर्थित डेटा प्रकारों में से एक होते हैं। लिस्प कोड, पार्सर द्वारा पढ़ने के बाद, डेटा संरचनाओं से बना होता है, जिसे आप ट्रैवर्स कर सकते हैं।

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

प्रोग्राम लिखने वाले प्रोग्राम? आप ऐसा कब करना चाहेंगे? बहुत बार नहीं, अगर आप कोबोल में सोचते हैं। हर समय, यदि आप लिस्प में सोचते हैं। अगर मैं एक शक्तिशाली मैक्रो का उदाहरण दे सकता हूं, और यहां कहना है तो यह सुविधाजनक होगा! उस के बारे में कैसा है? लेकिन अगर मैंने किया, तो यह सिर्फ लिबास के बारे में नहीं जानता, जो जिबरिश की तरह दिखाई देगा; वहाँ सब कुछ समझाने के लिए आपको यह जानने की आवश्यकता नहीं है कि इसका क्या मतलब है। में Ansi कॉमन लिस्प मैं जितनी जल्दी साथ के रूप में मैं कर सकता चीजों को स्थानांतरित करने की कोशिश की, और यहां तक कि इसलिए मैं पृष्ठ 160 तक मैक्रो को नहीं मिला।

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

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


6
C ++ में टेम्पलेट मेटाप्रोग्रामिंग के बारे में मत भूलना। अभिव्यक्तियों को निष्पादित करने और संकलन-समय पर निर्णय लेने की क्षमता, और परिणाम अंतिम रूप से निष्पादन योग्य रूप से संकलित किए जाते हैं।
रेमी लेबेउ

1
मैं चौंक गया था in order to put technical barriers between us and our competitorsऔर यह सही है।
इवान हू

4
ऐसे कार्यक्रम जो स्वयं में हेरफेर करते हैं, सभी मेटाप्रोग्राम्स का एक सबसेट हैं। सामान्य रूप से मेटाप्रोग्रामिंग का अर्थ उन कार्यक्रमों से है जो कार्यक्रमों में हेरफेर करते हैं।
जेडी

55

बड़ा सवाल है। मुझे यह देखकर बहुत अफ़सोस हुआ कि वर्तमान में कोई भी उत्तर आपके प्रश्न का सही उत्तर नहीं देता है। शायद मैं मदद कर सकता हूँ ...

मेटाप्रोग्रामिंग की परिभाषा वास्तव में काफी सरल है: इसका मतलब उन कार्यक्रमों से है जो कार्यक्रमों में हेरफेर करते हैं।

आपका स्वीकृत जवाब उन कार्यक्रमों को कहता है जो खुद को जोड़ते हैं। वे वास्तव में रूपक हैं लेकिन वे सभी रूपक हैं।

सब:

  • पारसर्स
  • डोमेन विशिष्ट भाषाएँ (DSLs)
  • एंबेडेड डोमेन विशिष्ट भाषाओं (EDSLs)
  • संकलनकर्ता
  • दुभाषियों
  • शब्द पुनर्लेखक
  • प्रमेय सिद्ध करता है

रूपक हैं। तो जीसीसी संकलक एक मेटाप्रोग्राम है, सीपीथॉन दुभाषिया एक मेटाप्रोग्राम है, मैथेमेटिका कंप्यूटर बीजगणित प्रणाली एक मेटाप्रोग्राम है, कोक प्रमेय प्रोवेर एक मेटाफ्रामग्राम है और इसी तरह।

अन्य उत्तरों ने जोर दिया है कि मेटाप्रोग्राम ऐसे प्रोग्राम हैं जो अन्य प्रोग्राम उत्पन्न करते हैं। वे वास्तव में रूपक हैं, लेकिन, फिर से, वे सभी रूपक हैं। सबसे तेजी से फूरियर पश्चिम में रूपांतरण (FFTW) पुस्तकालय इस तरह के एक metaprogram का एक उदाहरण है। स्रोत कोड ज्यादातर OCaml में लिखा गया है और यह C कोड (जिसे कोडलेट्स कहा जाता है) के बिट्स उत्पन्न करता है जो विशिष्ट मशीनों के लिए अनुकूलित उच्च प्रदर्शन फास्ट फूरियर ट्रांसफॉर्म रूटीन बनाने के लिए संयुक्त होते हैं । वह पुस्तकालय वास्तव में मतलाब में एफएफटी दिनचर्या प्रदान करने के लिए उपयोग किया जाता है। फोरट्रान के शुरुआती दिनों से, लोग दशकों से संख्यात्मक तरीकों को उत्पन्न करने के लिए कार्यक्रम लिख रहे हैं ।

पहली प्रोग्रामिंग भाषा जो मेटाप्रोग्रामिंग के लिए एकीकृत समर्थन थी, 1950 के दशक के उत्तरार्ध में LISt प्रोसेसर (LISP) भाषा थी। एलआईएसपी 1.5 में कई विशेषताएं शामिल थीं जो मेटाप्रोग्रामिंग को आसान बनाती हैं। सबसे पहले, LISP के मुख्य डेटा प्रकार में नेस्टेड सूचियाँ हैं, जैसे कि पेड़ (a (b c) d), जिसका अर्थ है कि कोई भी LISP कोड मूल रूप से डेटा संरचना के रूप में व्यक्त किया जा सकता है। इसे होमोसेक्सुअलिटी के रूप में जाना जाता है। दूसरे, एलआईएसपी कोड को आसानी से QUOTE का उपयोग करके डेटा में परिवर्तित किया जा सकता है। उदाहरण के लिए (+ 1 2 3)1 + 2 + 3 (QUOTE (+ 1 2 3))को जोड़ता है और मूल्यांकन करते समय 1 + 2 + 3 जोड़ता है जो एक अभिव्यक्ति बनाता है। तीसरा, LISP ने एक मेटा-सर्कुलर मूल्यांकनकर्ता प्रदान किया जो आपको रन-टाइम पर LISP कोड का मूल्यांकन करने के लिए होस्ट दुभाषिया या कंपाइलर का उपयोग करने की अनुमति देता है, जिसमें रन-टाइम जनरेट किया गया LISP कोड भी शामिल है। एलआईएसपी के वंशजों में स्कीम और क्लोजर शामिल हैं। इन सभी भाषाओं में मेटाप्रोग्रामिंग को आमतौर पर उन कार्यक्रमों के रूप में देखा जाता है जो स्वयं को संशोधित करते हैं, आमतौर पर मैक्रोज़ का उपयोग करते हैं।

1970 के दशक में रॉबिन मिलनर एक विकसित MetaLanguage (एमएल) कि भाषाओं जिसमें शामिल प्रोग्रामिंग की एमएल परिवार में विकसित मानक ML और OCaml और दृढ़ता से प्रभावित हास्केल और एफ # । इन भाषाओं से अन्य भाषाओं को व्यक्त करना आसान हो जाता है। इन भाषाओं में मेटाप्रोग्राम को आमतौर पर लेक्सर्स, पार्सर, दुभाषियों और संकलक के रूप में देखा जाता है।

1994 में, इरविन Unruh ने पाया कि C ++ टेम्प्लेट सिस्टम पूरी तरह से ट्यूरिंग था और इसका उपयोग अनिवार्य समय पर मनमाने कार्यक्रमों को निष्पादित करने के लिए किया जा सकता है । C ++ टेम्प्लेट मेटाप्रोग्रामिंग, मैटाप्रोग्रामिंग को उन अनचाही जनता तक पहुंचाता है जिन्होंने (ab) ब्लिट्ज ++ लाइब्रेरी में संख्यात्मक विधियों को बनाने सहित कई अलग-अलग चीजों के लिए इसका इस्तेमाल किया ।


33

ठीक है, मेटाप्रोग्रामिंग सिर्फ प्रोग्रामिंग है, लेकिन यह मूल रूप से "राइटिंग कोड है जो कोड लिखता है" है

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

डायनामिक रूप से टाइप की गई भाषाओं में शक्तिशाली रनटाइम प्रतिबिंब विशेषताएं होती हैं, जो इन भाषाओं की व्याख्या की गई प्रकृति से संभव होती है ...

स्टेटिक टाइप की गई भाषाओं में शक्तिशाली मेटाप्रोग्रामिंग तकनीक भी होती है, उदाहरण के लिए C ++ टेम्पलेट मेटाप्रोग्रामिंग ...


14

यह सिर्फ मेरी व्यक्तिगत राय है, जो शायद मेटाप्रोग्रामिंग की सबसे उदार परिभाषा है।

मुझे लगता है कि इसमें शामिल हैं:

  1. संकलन कोड पीढ़ी या रनटाइम कोड पीढ़ी (या दोनों)
  2. पहलू-उन्मुख सोच या पहलू उन्मुख प्रोग्रामिंग
  3. DRY की सोच

मुझे लगता है कि आप इनमें से किसी के संयोजन का उपयोग करके वहां पहुंच सकते हैं:

  1. प्रतिबिंब
  2. DSLs (डोमेन विशिष्ट भाषाएँ)
  3. विशेषताएँ (.NET) या एनोटेशन (जावा)
  4. जेनरिक (.NET / Java)
  5. टेम्प्लेट (C ++)
  6. method_missing (रूबी)
  7. क्लोजर / प्रथम श्रेणी के कार्य / प्रतिनिधि
  8. एओपी - पहलू ओरिएंटेड प्रोग्रामिंग

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

6

मेटाप्रोग्रामिंग एक प्रोग्राम लिख रहा है जो दूसरे प्रोग्राम को आउटपुट करता है। यह कुछ ऐसी भाषाएं हैं जैसे लिस्प वास्तव में बहुत अच्छी हैं। ऐसी भाषा में करना बहुत आसान है जो वास्तविक मैक्रोज़ का समर्थन करता है (सी ++ मैक्रोज़ नहीं, बल्कि वे जो कोड को आउटपुट में हेरफेर कर सकते हैं) जैसे कि रूबी, लिस्प, स्कीम, आदि जैसी भाषा में जावा।

एक कार्यान्वयन "डोमेन विशिष्ट भाषा" बनाना है जो किसी विशिष्ट कार्य को पूरा करने के लिए प्रोग्रामिंग भाषा को बढ़ाने का एक तरीका है। अगर सही ढंग से किया जाए तो यह अविश्वसनीय रूप से शक्तिशाली हो सकता है। रूबी ऑन रेल्स इस तरह की प्रोग्रामिंग का एक अच्छा उदाहरण है।

यदि आप इस विधि की खोज में रुचि रखते हैं, तो कंप्यूटर प्रोग्राम की संरचना और व्याख्या की जाँच करें जो विषय को कवर करने वाली सेमिनल पुस्तकों में से एक है।


5

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

असल में, यह कोड लिख रहा है जो अधिक कोड को आउटपुट करता है, जो कुछ लक्ष्य को पूरा करने के लिए चलाया जाता है। यह आमतौर पर या तो उसी भाषा के भीतर किया जाता है (जावास्क्रिप्ट स्ट्रिंग बनाने के लिए जावास्क्रिप्ट का उपयोग करके, फिर evalयह) या किसी अन्य भाषा का उपयोग करने के लिए (विंडोज़ बैच फ़ाइल बनाने के लिए .NET का उपयोग करके)।


4

विकिपीडिया विषय पर एक अच्छा लेख है। किसी को मेटाप्रोग्रामिंग के रूप में अर्हता प्राप्त करने के लिए रनटाइम संशोधन नहीं करना पड़ता है। उदाहरण के लिए, कई लोग संकलन समय पर मेटाप्रोग्रामिंग करने के लिए C ++ टेम्प्लेट का उपयोग करते हैं।

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