Метапрограммирование - сам объяснительный код - учебные руководства, статьи, [закрытые] книги

19
задан Darius Bacon 2 April 2010 в 07:54
поделиться

6 ответов

Что ж, в экосистеме Java я думаю, что самый простой способ реализовать мини-язык - использовать языки сценариев, такие как Groovy или Ruby (да, я знаю, Ruby не является родным гражданином экосистемы Java). Оба предлагают довольно хороший механизм спецификации DSL, который позволит вам сделать это с гораздо большей простотой, чем это сделал бы язык Java:

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

0
ответ дан 30 November 2019 в 03:19
поделиться

Из вашего примера кажется, что вы говорите о доменных языках (DSL), в частности, о внутренних DSL.

Здесь большой список книг о DSL в целом (о DSL, таких как SQL).

У Мартина Фаулера есть книга, работа над которой еще не завершена, и в настоящее время она онлайн .

Айенде написал книгу о DSL в boo .

Обновление : (следующие комментарии)

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

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

3
ответ дан 30 November 2019 в 03:19
поделиться

Добро пожаловать в чудесный мир метапрограммирования :) Мета-программирование действительно связано со многими вещами. Попробую перечислить, что придет мне в голову:

  • Macro . Возможность расширения синтаксиса и семантики языка программирования сначала была исследована в рамках терминологического макроса . Некоторые языки имеют конструкции, похожие на макросы, но выбор, конечно же, Lisp . Если вы интересуетесь метапрограммированием, понимание Лиспа и макросистемы (а также гомоиконной природы языка, где код и данные имеют одинаковое представление), безусловно, является обязательным. Если вам нужен диалект Лиспа, работающий на JVM, выберите Clojure . Несколько ресурсов:

    В остальном по Lisp имеется множество ресурсов.

  • DSL . Возможность расширения синтаксиса и семантики одного языка теперь переименована в термин «DSL». Самый простой способ создать DSL - использовать шаблон интерпретатора . Затем следует внутренний DSL с свободный интерфейс и внешний DSL (согласно терминологии Фаулера).Вот хорошее видео, которое я недавно смотрел:

    В других ответах уже указывались ресурсы в этой области.

  • Отражение . Мета-программирование - это тоже неотделимая форма отражения. Способность размышлять о структуре программы во время выполнения чрезвычайно эффективна. Тогда важно понять, что такое интроспекция , ходатайство и овеществление . IMHO, отражение допускает две широкие категории вещей: 1. манипулирование данными, структура которых неизвестна во время компиляции (структура данных затем предоставляется во время выполнения, и программа по-прежнему работает рефлексивно). 2. мощные шаблоны программирования, такие как динамический прокси , фабрики и т. Д. Smalltalk - лучший вариант для исследования отражения, где все является отражающим. Но я думаю, что Ruby также является хорошим кандидатом для этого с сообществом, которое использует метапрограммирование (но я сам мало что знаю о Ruby).

    Существует также обширная литература по рефлексии.

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

  • Байт-код или преобразование AST . Это можно сделать во время компиляции или во время выполнения. Это в некотором роде низкоуровневый подход, но его также можно рассматривать как форму метапрограммирования (в некотором смысле это то же самое, что и макрос для негомоиконного языка.)

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

Некоторые вещи подпадают под действие метапрограммирования. Судя по вашему вопросу, вас больше интересует часть макросов / DSL. Но в конечном итоге все взаимосвязано, поэтому стоит обратить внимание на другие аспекты метапрограммирования.

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

33
ответ дан 30 November 2019 в 03:19
поделиться

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

Если вам нужна реализация, интегрированная с Java, Jacl - это реализация Tcl в Java, которая обеспечивает возможность создания сценариев, ориентированных на DSL, а также доступ к получить доступ к любому объекту Java.

(Метапрограммирование - это написание программ, которые пишут программы. Некоторые языки делают это гораздо больше, чем другие. Если взять несколько конкретных случаев, Lisp - классический пример языка, который выполняет много метапрограммирования; C ++ имеет тенденцию относить его к категории к шаблонам, которые позволяют это во время выполнения; все языки сценариев склонны находить метапрограммирование более легким, потому что их реализации написаны таким образом более гибкими, хотя это всего лишь вопрос степени ..)

1
ответ дан 30 November 2019 в 03:19
поделиться

Я уже упоминал метапрограммирование шаблонов C++ в своем комментарии выше. Поэтому позвольте мне привести краткий пример использования метапрограммирования шаблонов C++. Я знаю, что вы пометили свой вопрос как java, но это может быть полезно. Я надеюсь, что вы сможете понять код на C++.


Демонстрация на примере:

Рассмотрим следующую рекурсивную функцию, которая генерирует ряд Фибоначчи (0, 1, 1, 2, 3, 5, 8, 13, ...):

unsigned int fib(unsigned int n)
{
    return n >= 2 ? fib(n-2) + fib(n-1) : n;
}

Чтобы получить элемент из ряда Фибоначчи, вы вызываете эту функцию - например, fib(5) - и она вычисляет значение и возвращает его вам. Пока ничего особенного.


Но теперь в C++ вы можете переписать этот код, используя шаблоны (несколько похожие на generics в Java), так что ряд Фибоначчи будет генерироваться не во время выполнения, а во время компиляции:

// fib(n) := fib(n-2) + fib(n-1)
template <unsigned int n>
struct fib                     // <-- this is the generic version fib<n>
{
    static const unsigned int value = fib<n-2>::value + fib<n-1>::value;
};

// fib(0) := 0
template <>
struct fib<0>                  // <-- this overrides the generic fib<n> for n = 0
{
    static const unsigned int value = 0;
};

// fib(1) := 1
template <>
struct fib<1>                  // <-- this overrides the generic fib<n> for n = 1
{
    static const unsigned int value = 1;
};

Чтобы получить элемент из ряда Фибоначчи, используя этот шаблон, просто получите постоянное значение -- например, fib<5>::value.


Вывод ("Какое отношение это имеет к метапрограммированию?"):

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

Поэтому это одна из форм метапрограммирования:

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

-- Определение из статьи Википедии о метапрограммировании, выделено мной.

(Обратите также внимание на побочные эффекты в приведенном выше примере шаблона: Поскольку вы заставляете компилятор предварительно вычислять числа Фибоначчи, их нужно где-то хранить. Размер двоичного файла вашей программы увеличится пропорционально наибольшему n, который используется в выражениях, содержащих термин fib::value. С другой стороны, вы экономите время вычислений во время выполнения)

.
3
ответ дан 30 November 2019 в 03:19
поделиться

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

0
ответ дан 30 November 2019 в 03:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: