Что такое метапрограммирование?

Я читал статью о TheServerSide на программировании ployglot на платформе Java. Некоторые комментарии в статье относятся к метапрограммированию как к способности генерировать код (возможно, "на лету" ).

Является метапрограммированием способности генерировать код "на лету" или это возможность внедрять методы и атрибуты в существующие объекты во время выполнения (например, разрешить некоторые динамические языки, такие как Python, Ruby и Groovy).

Ответ 1

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

В таких языках, как С#, отражение является формой метапрограммирования, поскольку программа может анализировать информацию о себе. Например, возвращает список всех свойств объекта.

В таких языках, как ActionScript, вы можете оценивать функции во время выполнения для создания новых программ, таких как eval ( "x" + i).DoSomething() влияет на объект с именем x1, когда я равно 1 и x2, когда я равно 2.

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

Также стоит отметить, что в хорошие времена программирования в прямом сборке программы, которые изменились во время выполнения, были необходимы и очень распространены.

Из эссе Пола Грэма "Что сделано LISP Разное" :

На многих языках есть нечто, называемое макро. Но макросы LISP уникальны. А также верьте или нет, что они делают связанных с круглыми скобками. дизайнеры LISP не поставили все эти скобки на языке, чтобы быть другой. Для программиста Blub, LISP код выглядит странно. Но эти в скобках есть причина. Это внешнее доказательство фундаментальное различие между Lispи другие языки.

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

Если вы понимаете, как работают компиляторы, что на самом деле происходит не так много что LISP имеет странный синтаксис, такой как LISP не имеет синтаксиса. Вы пишете программы в деревьях разбора, которые генерируются в компиляторе, когда другие языки анализируются. Но этот синтаксический анализ деревья полностью доступны для вашего программы. Вы можете писать программы, которые манипулировать ими. В Lisp эти программы называются макросами. Они есть программы, которые пишут программы.

Программы, которые пишут программы? когда вы когда-нибудь захотите это сделать? Не очень часто, если вы думаете в Cobol. Все время, если вы думаете в Lisp. Это было бы удобно здесь, если бы я мог дайте пример мощного макроса, и сказать там! как насчет этого? Но если Я сделал, это будет просто выглядеть тарабарщину тому, кто не знал Lisp; здесь нет места для объяснения все, что вам нужно знать понять, что это значит. В Ansi Общий Lisp Я пытался переместить вещи так быстро, как я мог, и даже так Я не добирался до макросов до страницы 160.

Но я думаю, что могу дать своего рода аргумент, который может быть убедительным. Исходный код редактора Viaweb был вероятно, около 20-25% макросов. макрос сложнее писать, чем обычные Lispфункций, и он считается плохой стиль, чтобы использовать их, когда они не необходимо. Поэтому каждый макрос в этом коде есть, потому что это должно быть. Какие это означает, что по меньшей мере 20-25% код в этой программе вещи, которые вы не можете легко сделать в любом другой язык. Однако скептически Программист Blub может быть о моем претензии на таинственные полномочия Lisp, это должно сделать его любопытным. Мы не писали этот код для нашего собственное развлечение. Мы были крошечным стартапом, программирования, насколько это было возможно в приложить технические барьеры между нами и нашими конкурентами.

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

Ответ 2

Ну, метапрограммирование - это просто программирование, но в основном это "написание кода, который пишет код".

Способность, которую вы упоминаете, когда программа может наблюдать и изменять свою собственную структуру и поведение, называется отражением, и это тип метапрограммирования.

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

Статические типизированные языки также имеют мощные методы метапрограммирования, например, метапрограммирование шаблона С++ ...

Ответ 3

Отличный вопрос. Мне очень жаль, что ни один из ответов в настоящее время не отвечает на ваш вопрос правильно. Возможно, я могу помочь...

Определение метапрограммирования действительно довольно просто: это программы, которые управляют программами.

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

Все:

  • Парсеры
  • Языки, относящиеся к домену (DSL)
  • Встроенные доменные языки (EDSL)
  • Составители
  • интерпретаторы
  • Переводчики терминов
  • Теоретические провизоры

являются метапрограммами. Таким образом, компилятор GCC является метапрограммой, интерпретатор CPython является метапрограммой, система компьютерной алгебры Mathematica является метапрограммой, теорема Кок-теоремы является метапрограммой и т.д.

Другие ответы утверждают, что метапрограммы - это программы, которые генерируют другие программы. Это действительно метапрограммы, но, опять же, они являются подмножеством всех метапрограмм. Быстрое преобразование Фурье на Западе (FFTW) - пример такой метапрограммы. Исходный код написан в основном OCaml и генерирует биты кода C (называемые кодами), которые объединены для создания высокопроизводительных Быстрое преобразование Фурье, оптимизированное для определенных машин. Эта библиотека фактически используется для предоставления процедур FFT в Matlab. Люди пишут программы для создания численных методов на протяжении десятилетий, начиная с ранних дней FORTRAN.

Первым языком программирования, который интегрировал поддержку метапрограммирования, был язык LISt Processor (LISP) в конце 1950-х годов. LISP 1.5 включил ряд функций, облегчающих метапрограммирование. Во-первых, тип данных типа LISP представляет собой вложенные списки, т.е. Деревья, такие как (a (b c) d), что означает, что любой код LISP может выражаться изначально как структура данных. Это называется гомоконичностью. Во-вторых, код LISP можно легко преобразовать в данные с помощью QUOTE. Например, (+ 1 2 3) добавляет 1 + 2 + 3 и (QUOTE (+ 1 2 3)) создает выражение, которое добавляет 1 + 2 + 3 при оценке. В-третьих, LISP предоставил мета-круговой оценщик, который позволяет использовать интерпретатор или компилятор хоста для оценки кода LISP во время выполнения, включая код, созданный во время выполнения LISP. Среди потомков LISP Scheme и Clojure. Во всех этих языках метапрограммирование чаще всего рассматривается в виде программ, которые изменяют себя, обычно используя макросы.

В 1970-х годах Робин Милнер разработала MetaLanguage (ML), который превратился в семейство языков программирования ML, которое включает Стандарт ML и OCaml и сильно повлияли на Haskell и F #. Эти языки упрощают выражение других языков. На этих языках метапрограммы чаще всего видны в виде лексеров, парсеров, интерпретаторов и компиляторов.

В 1994 году Эрвин Унрух обнаружил, что система шаблонов С++ полностью дополнена Turing и может быть использована для выполнения произвольных программ во время компиляции. Метапрограммирование шаблонов С++ приводило метапрограммирование к немытым массам, которые (ab) использовали его для многих разных вещей, включая создание численных методов в библиотеке Blitz ++.

Ответ 4

Это только мое личное мнение, которое, вероятно, является самым либеральным определением метапрограммирования.

Я думаю, что он включает в себя:

  • Генерация кода компиляции или генерация кода времени выполнения (или оба)
  • Аспектно-ориентированное мышление или аспектно-ориентированное программирование
  • DRY Мышление

Я думаю, вы можете добраться туда, используя любой из них и в комбинации:

  • Отражение
  • DSL (Языки домена)
  • Атрибуты (.NET) или аннотации (Java)
  • Общие (.NET/Java)
  • Шаблоны (С++)
  • method_missing (Ruby)
  • закрытия/функции/делегаты первого класса
  • AOP - Аспектно-ориентированное программирование

Ответ 5

Метапрограммирование записывает программу, которая выводит другую программу. Это действительно языки, такие как Lisp. Это гораздо проще сделать на языке, который поддерживает реальные макросы (а не макросы С++, а скорее те, которые могут манипулировать выводимым кодом), такие как Ruby, Lisp, Scheme и т.д., Чем на языке Java.

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

Если вам интересно изучить этот метод, ознакомьтесь с Structure and Interpretation of Computer Programs, который является одной из основных книг, посвященных этому вопросу.

Ответ 6

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

В принципе, он пишет код, который выводит больше кода, который запускается для достижения определенной цели. Обычно это делается на одном языке (с помощью javascript для создания строки javascript, затем eval it) или для испускания другого языка (с помощью .NET для создания пакетного файла Windows).

Ответ 7

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