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


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

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

7 89

7 ответов:

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

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

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

из эссе Пола Грэма "Что Сделало Lisp Другим":

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

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

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

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

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

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

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

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

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

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

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

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

все:

  • Парсеры
  • домен конкретные языки (DSLs)
  • встроенный предметно-ориентированные языки (EDSLs)
  • Сост
  • переводчики
  • термин рерайтеров
  • теорема доказывает

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

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

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

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

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

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

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

  1. генерация кода компиляции или генерация кода во время выполнения (или оба)
  2. аспектно-ориентированное мышление или аспектно-ориентированное программирование
  3. сухой мышление

Я думаю, что вы можете получить там с помощью любого из них и в сочетании:

  1. отражение
  2. DSLs (Доменные Языки)
  3. атрибуты (.NET) или аннотации (Java)
  4. дженерики (.NET / Java)
  5. Шаблоны (C++)
  6. method_missing (Ruby)
  7. замыкания / функции первого класса / делегаты
  8. AOP-аспектно-ориентированное программирование

метапрограммирование-это написание программы, которая выводит другую программу. Это то, что языки, такие как Lisp, действительно хороши. Это гораздо проще сделать на языке, который поддерживает реальные макросы (не макросы C++, а скорее те, которые могут манипулировать кодом, который они выводят), такие как Ruby, Lisp, Scheme и т. д. чем на таком языке, как Java.

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

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

источник.)

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

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