2009-02-05 13 views
76

मैं ployglot programming on the Java platform पर TheServerSide पर एक लेख पढ़ रहा था। लेख में कुछ टिप्पणियां मेटाप्रोग्रामिंग को कोड उत्पन्न करने की क्षमता के रूप में संदर्भित करती हैं (शायद फ्लाई पर)।मेटाप्रोग्रामिंग वास्तव में क्या है?

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

+5

आपको इस जवाब में रुचि हो सकती है http://stackoverflow.com/questions/2565572/metaprogramming-self-explanatory-code-tutorials-articles-books/2566561#2566561 – ewernli

+0

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

उत्तर

55

मेटाप्रोग्रामिंग विभिन्न तरीकों से संदर्भित करता है कि किसी प्रोग्राम को स्वयं का ज्ञान होता है या खुद को कुशल बना सकता है।

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

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

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

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

पॉल ग्राहम निबंध "What Made Lisp Different" से:

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

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

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

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

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

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

+4

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

+1

मैं और हमारे प्रतिस्पर्धियों के बीच तकनीकी बाधाओं को रखने के लिए 'चौंक गया था और यह सही है। –

+1

प्रोग्राम जो स्वयं को कुशल बनाते हैं वे सभी मेटाप्रोग्रामों का सबसेट हैं। मेटाप्रोग्रामिंग सामान्य रूप से केवल उन कार्यक्रमों का अर्थ है जो प्रोग्रामों में हेरफेर करते हैं। –

4

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

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

3

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

5

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

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

यदि आप इस विधि की खोज में रूचि रखते हैं, तो Structure and Interpretation of Computer Programs देखें जो विषय को कवर करने वाली मौलिक पुस्तकों में से एक है।

23

खैर, metaprogramming सिर्फ प्रोग्रामिंग है, लेकिन यह मूल रूप से "लिख कोड है कि लिखते कोड" है।

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

गतिशील रूप से भाषाओं टाइप किया, शक्तिशाली क्रम प्रतिबिंब सुविधाओं, इन भाषाओं में से व्याख्या की प्रकृति द्वारा ही संभव बनाया है ...

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

7

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

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

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

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

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

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

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

आपका स्वीकृत उत्तर उन कार्यक्रमों का कहना है जो स्वयं को कुशल बनाते हैं। वे वास्तव में मेटाप्रोग्राम हैं लेकिन वे सभी मेटाप्रोग्रामों का सबसेट हैं।

सभी

:

  • Parsers
  • डोमेन विशिष्ट भाषाओं (DSLs)
  • एंबेडेड डोमेन विशिष्ट भाषाओं (EDSLs)
  • संकलनकर्ता
  • दुभाषियों
  • टर्म rewriters
  • प्रमेय Provers

मेटाप्रोग्राम हैं। तो GCC compiler एक मेटाप्रोग्राम है, CPython interpreter एक मेटाप्रोग्राम है, एक मेटाप्रोग्राम है, Coq theorem prover एक मेटाप्रोग्राम है और इसी तरह।

अन्य उत्तरों ने जोर दिया है कि मेटाप्रोग्राम ऐसे प्रोग्राम हैं जो अन्य प्रोग्राम उत्पन्न करते हैं। वे वास्तव में मेटाप्रोग्राम हैं लेकिन फिर, वे सभी मेटाप्रोग्रामों का सबसेट हैं। Fastest Fourier Transform in the West (एफएफटीडब्ल्यू) पुस्तकालय ऐसे मेटाप्रोग्राम का एक उदाहरण है। स्रोत कोड ज्यादातर OCaml में लिखा गया है और यह सी कोड (कोडलेट कहा जाता है) के बिट्स उत्पन्न करता है जो विशिष्ट मशीनों के लिए अनुकूलित उच्च प्रदर्शन Fast Fourier Transform दिनचर्या बनाने के लिए संयुक्त होते हैं। उस पुस्तकालय का उपयोग वास्तव में मैटलैब में एफएफटी दिनचर्या प्रदान करने के लिए किया जाता है। लोग FORTRAN के प्रारंभिक दिनों से दशकों तक संख्यात्मक तरीकों को उत्पन्न करने के लिए कार्यक्रम लिख रहे हैं।

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

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

1 99 4 में, Erwin Unruh discovered that the C++ template system was Turing complete and could be used to execute arbitrary programs at compile time। सी ++ टेम्पलेट मेटाप्रोग्रामिंग ने अवांछित लोगों को मेटाप्रोग्रामिंग लाया जो (एबी) ने Blitz++ library में संख्यात्मक तरीकों को उत्पन्न करने सहित कई अलग-अलग चीजों के लिए इसका इस्तेमाल किया।

संबंधित मुद्दे