14

अंतर क्या है? ऐसा लगता है मामले में कुछ हद तक दूसरे के स्थान पर इस्तेमाल किया जा सकता की तरह है, लेकिन ऑब्जेक्टिव-सी के लिए विकिपीडिया प्रविष्टि पढ़ने, मैं भर में आया था:जेनेरिक प्रोग्रामिंग बनाम। मेटाप्रोग्रामिंग

प्रक्रियात्मक प्रोग्रामिंग की सी की शैली के अलावा, सी ++ सीधे वस्तु के कुछ रूपों का समर्थन करता है उन्मुख प्रोग्रामिंग, जेनेरिक प्रोग्रामिंग, और मेटाप्रोग्रामिंग।

सी ++ के संदर्भ में। तो जाहिर है वे अलग हैं?

+0

ऑफ़टॉप भाषाई प्रश्न: vs.s. या बनाम? - "बनाम" बनाम "बनाम" :) –

+2

@ आर्मेन: यह भी सवाल लाता है: "बनाम बनाम बनाम" बनाम "बनाम बनाम बनाम"? – Claudiu

+3

@ क्लाउडियो: और पवित्र रिकर्सन रिकर्स दें! : डी –

उत्तर

12

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

इस उत्तर के लिए टिप्पणियों पर विचार के बाद संपादित

+1

हां, आप टेम्पलेट को मेटाप्रोग्राम के रूप में सोच सकते हैं, लेकिन आप उदाहरण के साथ वास्तव में ऐसा नहीं कर सकते हैं जावा जेनेरिक। तो मैं कहूंगा: जेनेरिक प्रोग्रामिंग मेटाप्रोग्रामिंग का उपयोग करके हासिल किया जा सकता है, लेकिन यह एकमात्र तरीका नहीं है। – sepp2k

+1

@ sepp2k: ठीक है, मैंने सी ++ में टेम्पलेट निर्दिष्ट किए हैं। लेकिन मैं मानता हूं कि अन्य भाषाओं में जेनेरिक प्रोग्रामिंग में मेटाप्रोग्रामिंग –

+0

@ sepp2k शामिल नहीं होना चाहिए: यह एक अच्छा बिंदु है जिसे मैंने केवल मेरे उत्तर में भी बताया है। आईएमओ जावा जेनरिक से एक बेहतर उदाहरण है (जिसमें कम से कम कंपाइलर में कंपाइलर से कुछ सहयोग शामिल है) सामान्य लिस्प में सामान्य कार्य होते हैं, जिसमें प्रेषण रनटाइम प्रकार (आईआईआरसी, मैं एक लिस्प नहीं हूं) द्वारा पूरी तरह से पूरा किया जाता है। विशेषज्ञ, अगर मैं गलत हूं तो मुझे सही करें)। –

4

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

मेटाप्रोग्रामिंग कक्षाओं, मॉड्यूल या प्रोग्राम प्रोग्रामेटिक रूप से निरीक्षण, संशोधन या निर्माण का संदर्भ देता है।

7

मैं मोटे तौर पर के रूप में "भाषा सुविधाओं का उपयोग कर काम करता है, कक्षाओं, आदि लिखने के लिए डेटा प्रकार पर parameterized के रूप में" कार्यक्रमों लेखन कार्यक्रमों लिखने के लिए "और सामान्य प्रोग्रामिंग metaprogramming परिभाषित करेगा तर्क या सदस्यों के "।

इस मानक के अनुसार, सी ++ टेम्पलेट्स (लगता है vector, list, sort ...) और metaprogramming (लगता है बूस्ट और जैसे आत्मा) दोनों सामान्य प्रोग्रामिंग के लिए उपयोगी होते हैं। इसके अलावा, मैं तर्क दूंगा कि सी ++ में सामान्य प्रोग्रामिंग (यानी संकलन-समय बहुरूपता) मेटाप्रोग्रामिंग द्वारा पूरा किया जाता है (यानी टेम्पलेट कोड से कोड जनरेशन)।

4

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

योजना/लिस्प में, आप अपने कोड के व्याकरण को बदल सकते हैं। लोग शायद योजना को "बहुत सारे ब्रांड्स के साथ उपसर्ग भाषा" के रूप में जानते हैं, लेकिन इसमें बहुत शक्तिशाली मेटाप्रोग्रामिंग तकनीकें भी हैं (हाइजेनिक मैक्रोज़)। विशेष रूप से, कोशिश करें/पकड़ बनाया जा सकता है, और यहां तक ​​कि व्याकरण को किसी बिंदु पर छेड़छाड़ की जा सकती है (उदाहरण के लिए, यदि आप उपसर्ग कोड अब और नहीं लिखना चाहते हैं तो इन्फिक्स कनवर्टर का उपसर्ग यहां है: http://github.com/marcomaggi/nausicaa)। यह मेटाप्रोग्रामिंग के माध्यम से पूरा किया जाता है, कोड जो कोड लिखता है जो कोड लिखता है। यह प्रोग्रामिंग के नए प्रतिमानों के प्रयोग के लिए उपयोगी है (एएमबी ऑपरेटर गैर-निर्धारक प्रोग्रामिंग में एक महत्वपूर्ण भूमिका निभाता है। मुझे उम्मीद है कि एएमबी अगले 5 वर्षों में मुख्यधारा बन जाएगा या नहीं ...)

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

जहां चीजें अजीब होती हैं, यह है कि सी ++ टेम्पलेट जेनेरिक प्रोग्रामिंग के लिए डिज़ाइन किए गए हैं। हालांकि, कुछ चालों के कारण, सी ++ टेम्पलेट स्वयं ट्यूरिंग-पूर्ण हैं। इन चालों का उपयोग करके, मेटा-प्रोग्रामिंग के माध्यम से सी ++ भाषा में नई सुविधाएं जोड़ना संभव है। यह गड़बड़ है, लेकिन यह काम करता है। यहां एक उदाहरण दिया गया है जो टेम्पलेट्स के माध्यम से सी ++ में एकाधिक प्रेषण जोड़ता है। http://www.eptacom.net/pubblicazioni/pub_eng/mdisp.html। अधिक विशिष्ट उदाहरण संकलन समय पर फाइबोनैचि है: http://blog.emptycrate.com/node/271

32
  • प्रोग्रामिंग: एक प्रोग्राम है जो बनाता है, बदल देती है, फिल्टर, समुच्चय और अन्यथा डेटा manipulates लेखन।
  • मेटाप्रोग्रामिंग: एक प्रोग्राम लिखना जो बनाता है, बदलता है, फ़िल्टर करता है, एकत्र करता है और अन्यथा प्रोग्राम का उपयोग करता है।
  • जेनेरिक प्रोग्रामिंग: एक प्रोग्राम लिखना जो डेटा बनाता है, ट्रांसफॉर्म करता है, फ़िल्टर करता है, समेकित करता है और अन्यथा मैनिपुलेट करता है, लेकिन डेटा की संरचना के बारे में केवल न्यूनतम मान्यताओं को बनाता है, इस प्रकार डेटाटाइप की एक विस्तृत श्रृंखला में पुन: उपयोग को अधिकतम करता है।

जैसा कि पहले से ही कई अन्य उत्तरों में उल्लेख किया गया था, भेद सी ++ में भ्रमित हो सकता है, क्योंकि जेनेरिक प्रोग्रामिंग और (स्थिर/संकलन समय) मेटाप्रोग्रामिंग टेम्पलेट्स के साथ किया जाता है। आपको और भी भ्रमित करने के लिए, सी ++ में जेनेरिक प्रोग्रामिंग वास्तव में कुशल होने के लिए मेटाप्रोग्रामिंग का उपयोग करती है, यानी टेम्पलेट विशेषज्ञता जेनेरिक से विशेष (तेज़) प्रोग्राम उत्पन्न करती है।

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

कई अन्य भाषाओं दोनों प्रोग्रामिंग और metaprogramming के लिए एक ही भाषा का प्रयोग (जैसे लिस्प, टेम्पलेट हास्केल, कन्वर्ज, स्मॉलटॉक, न्यूज़पीक, रूबी, इको, सेफ)।

0

सामान्य प्रोग्रामिंग आमतौर पर रनटाइम के बावजूद मेटाकोडिंग का एक बहुत ही सरल रूप है। यह सी में प्रीप्रोसेसर की तरह है और अधिकांश उपयोग मामलों और बुनियादी कार्यान्वयन में टेम्पलेट प्रोग्रामिंग से अधिक संबंधित है।

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

आप उन वर्गों को उन्हें स्ट्रिंग अक्षर में परिवर्तित करके उत्पन्न कर सकते हैं और कक्षा के नाम को एक चर के साथ इंटरपोलेट में बदल सकते हैं।

जहां जेनिक्स रनटाइम में उपयोग किया जाता है, यह थोड़ा अलग है, उस स्थिति में यह चर परिवर्तनीय प्रोग्रामिंग, चर का उपयोग कर प्रोग्रामिंग है।

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

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

परिवर्तनशीलता नहीं होने का प्रभाव जहां आपको इसकी आवश्यकता है, अपने चर को अनलॉक करना है, जिसे आप प्रत्येक चर के लिए कार्यान्वयन करने के लिए चर बदलने के बजाय मजबूर हैं।

जैसा कि आप कल्पना कर सकते हैं कि यह काफी महंगा है। किसी भी तरह की पुन: प्रयोजन वस्तु भंडारण पुस्तकालय का उपयोग करते समय यह बहुत आम होगा। ये किसी ऑब्जेक्ट को स्वीकार करेंगे लेकिन ज्यादातर मामलों में लोग केवल एक प्रकार का objdct पीड़ित करना चाहते हैं। यदि आप ऑब्जेक्ट को विस्तारित करते हुए एक शॉप ऑब्जेक्ट डालते हैं तो उसे पुनर्प्राप्त करना चाहते हैं, तो स्टोरेज ऑब्जेक्ट पर विधि हस्ताक्षर केवल ऑब्जेक्ट लौटाएगा लेकिन आपका कोड शॉप ऑब्जेक्ट की अपेक्षा करेगा। यह ऑब्जेक्ट के डाउनग्रेड के साथ संकलन तोड़ देगा जबतक कि आप इसे वापस खरीदने के लिए नहीं डालते। यह जेनरिक के बिना एक और conundrum उठाता है संगतता की जांच करने के लिए कोई रास्ता नहीं है और सुनिश्चित करें कि आप जिस वस्तु को संग्रहित कर रहे हैं वह एक दुकान वर्ग है।

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

प्रोग्रामिंग भाषाएं जो लैवेज मेटाकोडिंग सुविधाओं की पेशकश करती हैं, विशेष मामलों, प्रतिबिंब, ओओपी पॉलिमॉर्फिज्म इत्यादि को छोड़ने से बचने के बजाय भाषाओं की तुलना में काफी अधिक उत्पादक हो सकती हैं। हालांकि यह अक्सर un = nderstandable, maintainaiable उत्पन्न करने के लिए बहुत अधिक कौशल और विशेषज्ञता लेता है और बग फ्री कोड। ऐसी भाषाओं के लिए अक्सर एक प्रदर्शन जुर्माना भी होता है जिसमें सी ++ एक विषम गेंद के साथ होता है क्योंकि यह मूल के लिए संकलित होता है।