14

В чем же разница? Похоже, что термины могут быть использованы несколько взаимозаменяемы, но прочитав статью в Википедии для Objective-C, я наткнулся на:Общее программирование vs. Метапрограммирование

В дополнение к стилю языка C процедурного программирования C++ непосредственно поддерживает определенные формы object- ориентированное программирование, общее программирование, метапрограммирование.

применительно к C++. По-видимому, они разные?

+0

Оффтоп лингвистический вопрос: v.s. или против? - "vs.s." против "против" :) –

+2

@Armen: это также ставит вопрос: «vs.s. vs. vs.» vs. vs. vs.s. vs. "? – Claudiu

+3

@ Claudiu: И пусть регрессия святой рекурсии! : D –

ответ

12

Метапрограммирование в широком смысле означает написание программ, которые дают другие программы. Например. подобные шаблоны в C++ выдает фактический код только при создании экземпляра. Можно интерпретировать шаблон как программу, которая принимает тип в качестве ввода и создает фактическую функцию/класс в качестве вывода. Препроцессор - это еще один вид метапрограммирования. Другой составленный пример метапрограммирования: программа, которая читает XML и создает некоторые SQL-скрипты в соответствии с XML. Опять же, в общем случае метапрограмма представляет собой программу, которая дает другую программу, тогда как общее программирование связано с параметризованными (обычно с другими типами) типами (включая функции).

EDITED после рассмотрения замечаний к этому ответу

+1

Да, вы можете думать о шаблоне как метапрограмме, но вы не может действительно сделать то же самое, например java generics. Поэтому я бы сказал: общее программирование может быть достигнуто с помощью метапрограммирования, но это не единственный способ. – sepp2k

+1

@ sepp2k: Ну, я указал шаблоны на C++. Но я согласен с тем, что в других языках общее программирование не обязательно должно включать метапрограммирование –

+0

@ sepp2k: это хороший момент, который я подразумевал только в своем ответе. IMO - еще лучший пример, чем Java-дженерики (которые включают по крайней мере некоторое сотрудничество со стороны компилятора в стирании типа) - это общие функции в Common Lisp, в которых отправка выполняется исключительно путем проверки типа времени выполнения (IIRC, я не Lisp эксперт, так исправьте меня, если я ошибаюсь). –

4

Общее программирование обычно относится к функциям, которые могут работать со многими типами. Например. функция сортировки, которая может сортировать коллекцию сравниваемых данных вместо одной функции сортировки для сортировки массива из int и другого для сортировки вектора строк.

Метапрограммирование относится к проверке, модификации или созданию классов, модулей или функций программным способом.

7

Я бы грубо определить метапрограммирование как «написание программы для написания программ» и обобщенное программирование, как «с использованием возможностей языка для написания функций, классов и т.д. параметрироваться на типах данных аргументов или членов ».

По этому стандарту, шаблоны C++ полезны как для общего программирования (думаю vector, list, sort ...) и метапрограммированием (думаю, подталкивание и, например, Дух). Более того, я хотел бы утверждать, что общее программирование в C++ (то есть полиморфизм времени компиляции) выполняется посредством метапрограммирования (то есть генерации кода из шаблонного кода).

4

Лучше всего смотреть на другие языки, потому что в C++ одна функция поддерживает как общее программирование, так и метапрограммирование. (Шаблоны очень мощные).

В Scheme/Lisp вы можете изменить грамматику своего кода. Люди, вероятно, знают Схему как «этот язык префикса с большим количеством скобок», но также имеют очень мощные методы метапрограммирования (Hygenic Macros). В частности, try/catch может быть создан, и даже грамматику можно манипулировать до точки (например, вот префикс для инфиксного конвертера, если вы больше не хотите писать префиксный код: http://github.com/marcomaggi/nausicaa). Это достигается посредством метапрограммирования, кода, который пишет код, который пишет код. Это полезно для экспериментов с новыми парадигмами программирования (оператор AMB играет важную роль в не детерминированном программировании. Надеюсь, AMB станет основным в следующие 5 лет или около того ...)

В Java/C# вы можете иметь общее программирование через дженерики. Вы можете написать один универсальный класс, который поддерживает типы многих других классов. Например, в Java вы можете использовать Vector для создания Vector of Integer. Или Vector, если вы хотите, чтобы это было специфично для вашего собственного класса.

Где все странно, что шаблоны C++ предназначены для общего программирования. Однако из-за нескольких трюков сами шаблоны C++ завершают работу. Используя эти трюки, можно добавить новые функции на язык C++ посредством метапрограммирования. Его запутанный, но он работает. Вот пример, который добавляет несколько отправки на C++ через шаблоны. http://www.eptacom.net/pubblicazioni/pub_eng/mdisp.html. Более типичный пример Фибоначчи во время компиляции: http://blog.emptycrate.com/node/271

32
  • Программирование: Написание программы, которая создает, преобразует, фильтры, агрегаты и иным образом манипулирует данными.
  • Метапрограммирование: Создание программы, которая создает, преобразует, фильтрует, объединяет и иным образом манипулирует программами.
  • Общее программирование: Написание программы, которая создает, преобразует, фильтрует, агрегатирует и иным образом манипулирует данными, но делает только минимальные предположения о структуре данных, тем самым максимизируя повторное использование в широком диапазоне типов данных.

Как уже упоминалось в нескольких других ответах, различие может сбивать с толку в C++, поскольку метапрограммирование как статического, так и компилируемого времени выполняется с помощью шаблонов. Чтобы смутить вас еще больше, Generic Programming на C++ фактически использует Metaprogramming, чтобы быть эффективными, т. Е. Специализация шаблонов генерирует специализированные (быстрые) программы из общих.

Также обратите внимание, что, как знает каждый программист Lisp, код и данные - одно и то же, поэтому на самом деле нет такой вещи, как «метапрограммирование», это всего лишь программирование. Опять же, это немного сложно увидеть на C++, так как вы фактически используете два совершенно разных языка программирования для программирования (C++, императивный, процедурный, объектно-ориентированный язык в семействе C) и метапрограммирование (Шаблоны, чисто функциональные "случайные "язык где-то между чистой лямбда-исчисления и Haskell, с прикладом уродливые синтаксиса, так как он никогда не был на самом деле намеревался быть язык программирования.)

Многие другие языки используют один и тот же язык программирования, так и метапрограммированием (например, Lisp, Template Haskell, Converge, Smalltalk, Newspeak, Ruby, Ioke, Seph).

0

Общее программирование - очень простая форма метакодирования, хотя обычно это не среда исполнения. Это больше похоже на препроцессор в C и больше относится к программированию шаблонов в большинстве случаев использования и базовых реализаций.

Вы часто найдете на типизированных языках, что вы создадите несколько реализаций чего-либо, где только тип, если он отличается. В таких языках, как Java, это может быть особенно болезненно, поскольку каждый класс и интерфейс определяют новый тип.

Вы можете сгенерировать эти классы, преобразовывая их в строковый литерал, а затем заменяя имя класса переменной для интерполяции.

Где обобщения используются во время выполнения, это немного отличается, в этом случае это просто переменное программирование, программирование с использованием переменных.

Способ предусмотреть, что это просто, взять в файлы, сравнить их и превратить что-то другое в переменную. Теперь у вас есть только один файл, который можно использовать повторно. Вам нужно только указать, что изменилось, отсюда и переменная имени.

Как возникли дженерики, что не все может быть изменено, как тип переменной, который вы ожидаете, или тип броска. Часто было много дублирования файлов, где единственной переменной, которая была переменной, были типы переменных. Это был очень распространенный источник дублирования. Хотя есть способы обойти это или смягчить, они не особенно удобны. Дженерики пришли как разновидность переменной, чтобы позволить переменную типа переменной. Поскольку тип переменной - это что-то, что обычно выражается на языке программирования, которое теперь может быть указано во время выполнения, это также считается метакодированием, хотя и очень простым.

Эффект отсутствия изменчивости там, где он вам нужен, заключается в том, чтобы развернуть ваши переменные, то есть вы вынуждены вместо того, чтобы иметь переменную, чтобы сделать реализацию для всех возможных значений переменной.

Как вы можете себе представить, это довольно дорого. Это было бы очень распространено при использовании любой библиотеки хранения объектов повторного использования. Они будут принимать любой объект, но в большинстве случаев люди хотят только ранить один тип objdct. Если вы добавите объект Shop, который расширяет Object, а затем хотите его получить, подпись метода на объекте хранения будет возвращать просто Object, но ваш код ожидает объект Shop. Это сломает компиляцию с понижением уровня объекта, если вы не вернете его обратно в магазин. Это вызывает еще одну загадку, так как без дженериков нет возможности проверить совместимость и гарантировать, что объект, который вы храните, является классом Shop.

Java избегает метапрограммирования и пытается упростить использование языка с использованием принципов полиморфизма ООП, чтобы сделать гибкий код. Однако есть некоторые насущные и повторяющиеся проблемы, которые через опыт представили и рассматриваются с добавлением минимальных средств метапрограммирования. Java не хочет быть языком метапрограммирования, но редко импортирует концепции оттуда, чтобы решить самые вопиющие проблемы.

Языки программирования, которые предлагают средства для метакодирования лаважа, могут быть значительно более производительными, чем языки, чем избегать его, запрещающего специальные случаи, отражение, полиморфизм ООП и т. Д. Однако для генерации un = nderstandable, maintaiable часто требуется гораздо больше навыков и знаний и код ошибки. Также часто наблюдается снижение производительности для таких языков, когда C++ является немного странным, потому что он скомпилирован в native.