Метапрограммирование - Википедия - Metaprogramming
Эта статья поднимает множество проблем. Пожалуйста помоги Улучши это или обсудите эти вопросы на страница обсуждения. (Узнайте, как и когда удалить эти сообщения-шаблоны) (Узнайте, как и когда удалить этот шаблон сообщения)
|
Метапрограммирование это метод программирования, в котором компьютерные программы имеют возможность рассматривать другие программы как свои данные. Это означает, что программа может быть разработана для чтения, генерации, анализа или преобразования других программ и даже для изменения самой себя во время работы.[1][2] В некоторых случаях это позволяет программистам минимизировать количество строк кода для выражения решения, что, в свою очередь, сокращает время разработки.[3] Это также обеспечивает большую гибкость программ для эффективной обработки новых ситуаций без перекомпиляции.
Метапрограммирование может использоваться для переноса вычислений из время выполнения к время компиляции, для генерации кода с использованием вычислений во время компиляции и для включения самомодифицирующийся код. Язык, на котором написана метапрограмма, называется метаязык. Язык управляемых программ называется атрибутивно-ориентированное программирование язык. Способность языка программирования быть собственным метаязыком называется отражение или «рефлексивность».[4] Отражение - это ценная языковая функция, облегчающая метапрограммирование.
Метапрограммирование было популярно в 1970-х и 1980-х годах с использованием языков обработки списков, таких как LISP. Аппаратные машины LISP были популярны в 1980-х годах и позволяли приложениям обрабатывать код. Их часто использовали для искусственный интеллект Приложения.
Подходы
Метапрограммирование позволяет разработчикам писать программы и разрабатывать код, подпадающий под общее программирование парадигма. Имея сам язык программирования как первоклассный тип данных (как в Лисп, Пролог, СНОБОЛ, или же Ребол ) тоже очень полезно; это известно как гомоиконность. Универсальное программирование вызывает средство метапрограммирования в языке, позволяя писать код, не заботясь об указании типов данных, поскольку они могут быть предоставлены как параметры при использовании.
Метапрограммирование обычно работает одним из трех способов.[5]
- Первый подход состоит в том, чтобы предоставить программному коду доступ к внутренностям механизма выполнения через интерфейсы прикладного программирования (API) как это для .СЕТЬ IL эмиттер.
- Второй подход - это динамическое выполнение выражений, которые содержат команды программирования, часто составленные из строк, но также могут исходить из других методов, использующих аргументы или контекст, например Javascript.[6] Таким образом, «программы могут писать программы». Хотя оба подхода могут использоваться в одном и том же языке, большинство языков склоняются к одному или другому.
- Третий подход - полностью выйти за пределы языка. Общее назначение преобразование программы такие системы, как компиляторы, которые принимают описания языков и выполняют произвольные преобразования на этих языках, являются прямыми реализациями общего метапрограммирования. Это позволяет применять метапрограммирование практически к любому целевому языку независимо от того, обладает ли этот целевой язык собственными способностями к метапрограммированию. Это можно увидеть при работе с Схема и как это позволяет преодолеть некоторые ограничения, с которыми C с помощью конструкций, которые были частью самого языка Scheme для расширения C.[7]
Лисп вероятно, наиболее существенный язык с возможностями метапрограммирования, как из-за его исторического преимущества, так и из-за простоты и мощности его метапрограммирования. В метапрограммировании Лиспа оператор отмены кавычек (обычно запятая) вводит код, который оценивается во время определения программы, а не во время выполнения; видеть Самооценка форм и цитирование в Лиспе. Таким образом, язык метапрограммирования идентичен основному языку программирования, а существующие процедуры Lisp при желании могут быть напрямую повторно использованы для метапрограммирования. Этот подход был реализован на других языках путем включения в программу интерпретатора, который работает непосредственно с данными программы. Существуют реализации такого рода для некоторых распространенных языков высокого уровня, таких как RemObjects ’ Скрипт Паскаля за Object Pascal.
Использование
Генерация кода
Вот простой пример метапрограммы. Оболочка POSIX сценарий, который является примером генеративное программирование:
#! / bin / sh# метапрограммаэхо '#! / bin / sh' > программаза я в $(seq 992)делать эхо "эхо $ i" >> программасделанопрограмма chmod + x
Этот сценарий (или программа) генерирует новую программу из 993 строк, которая выводит числа 1–992. Это только иллюстрация того, как использовать код для написания большего количества кода; это не самый эффективный способ распечатать список чисел. Тем не менее, программист может написать и выполнить эту метапрограмму менее чем за минуту и за это время сгенерирует более 1000 строк кода.
А лоза - это особый вид метапрограммы, который на выходе создает собственный исходный код. Квайны обычно представляют только развлекательный или теоретический интерес.
Не все метапрограммирование включает в себя генеративное программирование. Если программы можно изменять во время выполнения или доступна инкрементная компиляция (например, в C #, Четвертый, Фринк, Groovy, JavaScript, Лисп, Эликсир, Lua, Perl, PHP, Python, REBOL, Рубин, Ржавчина, SAS, Болтовня, и Tcl ), то можно использовать методы для выполнения метапрограммирования без фактического создания исходного кода.
Один из стилей генеративного подхода - использовать предметно-ориентированные языки (DSL). Довольно распространенный пример использования DSL включает в себя генеративное метапрограммирование: lex и yacc, два инструмента, используемых для создания лексические анализаторы и парсеры, позвольте пользователю описать язык, используя обычные выражения и контекстно-свободные грамматики, и встроить сложные алгоритмы, необходимые для эффективного синтаксического анализа языка.
Инструментарий кода
Одно из применений метапрограммирования - это инструментальные программы для выполнения динамический анализ программы.
Изменения в поведении
Метапрограммирование может использоваться для внесения поведенческих изменений в программу, как это сделано в аспектно-ориентированное программирование. Например, метапрограммирование можно использовать для внедрения флаги функций или изучить возможные патчи для исправления ошибок.[8]
Вызовы
Некоторые утверждают, что для полноценного использования функций метапрограммирования требуется резкая кривая обучения.[9] Поскольку метапрограммирование дает большую гибкость и настраиваемость во время выполнения, неправильное использование или неправильное использование метапрограммирования может привести к неоправданным и неожиданным ошибкам, отладку которых для среднего разработчика может быть чрезвычайно сложно. Он может внести риски в систему и сделать ее более уязвимой, если не использовать ее с осторожностью. Некоторые из распространенных проблем, которые могут возникнуть из-за неправильного использования метапрограммирования, - это неспособность компилятора идентифицировать отсутствующие параметры конфигурации, недопустимые или неверные данные могут привести к неизвестному исключению или другим результатам.[10] Из-за этого некоторые считают[9] что только высококвалифицированные разработчики должны работать над разработкой функций, которые осуществляют метапрограммирование на языке или платформе, а средние разработчики должны научиться использовать эти функции как часть соглашения.
Использование в языках программирования
Макросистемы
- Common Lisp и большинство Лисп диалекты.
- Схема гигиенические макросы
- MacroML
- Ракетка (язык программирования)
- Шаблон Haskell
- Scala макросы
- Clojure макросы
- Ним
- Ржавчина
- Haxe
- Юля
Макроассемблеры
В IBM / 360 и деривативы имели мощные макроассемблер объекты, которые часто использовались для создания полных язык ассемблера программы[нужна цитата ] или разделы программ (например, для разных операционных систем). Макросы, поставляемые с CICS обработка транзакции В системе были макросы ассемблера, которые генерировали операторы COBOL в качестве шага предварительной обработки.
Другие ассемблеры, такие как MASM, также поддерживают макросы.
Метаклассы
Метаклассы предоставляются следующими языками программирования:
Метапрограммирование шаблона
- C «X Macros»
- C ++ шаблоны
- D
- Common Lisp, Схема и в большинстве диалектов Лиспа с помощью оператора квазицитата ("обратная кавычка").[12]
- Ним
Поэтапное метапрограммирование
Зависимые типы
Использование зависимые типы позволяет доказать, что сгенерированный код никогда не является недействительным.[15] Однако этот подход является передовым и редко встречается за пределами исследовательских языков программирования.
Реализации
Список известных систем метапрограммирования поддерживается на Список систем трансформации программ.
Смотрите также
- Аспект ткачиха
- Сравнение инструментов генерации кода
- Отражение во время компиляции
- Генетическое программирование
- Гомоиконность
- Логическое программирование
- Симулятор набора инструкций
- Преднамеренное программирование
- Интерпретируемый язык
- Машинное обучение
- Метакомпилятор
- Метаобъект
- Частичная оценка
- Отражение (компьютерное программирование)
- Самостоятельный переводчик
- Самомодифицирующийся код
- Генерация исходного кода
- Транскомпилятор (также известный как транспиляция)
- Очень крупномасштабная интеграция
Рекомендации
- ^ Харальд Сондергаард. «Курс по анализу и трансформации программ». Получено 18 сентября 2014.
- ^ Чарнецкий, Кшиштоф; Эйзенекер, Ульрих В. (2000). Генеративное программирование. ISBN 0-201-30977-7.
- ^ Уокер, Макс. «Искусство метапрограммирования на Java». Новый круг. Получено 28 января 2014.
- ^ Краусс, Аарон. "Концепции программирования: самоанализ и размышление о типах". Общество. Получено 14 сентября 2014.
- ^ Джоши, Пратик. «Что такое метапрограммирование? - Часть 2/2». Вечная загадка. Получено 14 августа 2014.
- ^ например instance_eval в Рубин принимает строку или анонимную функцию. «Rdoc для класса: BasicObject (Ruby 1.9.3) - instance_eval». Получено 30 декабря 2011.
- ^ «Искусство метапрограммирования».
- ^ Дюрье, Томас; Корню, Бенуа; Сейнтюрье, Лайонел; Монперрус, Мартин (2017). «Генерация динамического патча для исключений с нулевым указателем с использованием метапрограммирования» (PDF). 24-я Международная конференция по анализу, эволюции и реинжинирингу программного обеспечения, IEEE, 2017 (SANER). IEEE: 349–358. Дои:10.1109 / SANER.2017.7884635. ISBN 978-1-5090-5501-2.
- ^ а б Бикинг, Ян. «Проблема метапрограммирования». IanBicking.org. Получено 21 сентября 2016.
- ^ Терри, Мэтт. «Остерегайтесь метапрограммирования». Medium.com. Средняя корпорация. Получено 21 августа 2014.
- ^ Через Общая объектная система Lisp "Протокол метаобъектов"
- ^ Лисп (язык программирования) «Самооценочные формы и цитирование», оператор квазицикции.
- ^ «LMS: создание программ и встроенные компиляторы в Scala». scala-lms.github.io. Получено 2017-12-06.
- ^ Rompf, Tiark; Одерский, Мартин (июнь 2012). «Облегченная модульная постановка: прагматический подход к генерации кода времени выполнения и скомпилированным DSL». Commun. ACM. 55 (6): 121–130. Дои:10.1145/2184319.2184345. ISSN 0001-0782.
- ^ Хлипала, Адам (июнь 2010 г.). "Ur: статически типизированное метапрограммирование с вычислением записей на уровне типа" (PDF). Уведомления ACM SIGPLAN. PLDI '10. 45 (6): 122–133. Дои:10.1145/1809028.1806612. Получено 29 августа 2012.
внешняя ссылка
- c2.com Wiki: статья о метапрограммировании
- Мета-программирование на вики по преобразованию программ
- Генерация кода против метапрограммирования
- «Соленоид»: Первая структура метапрограммирования для eXist-db