http://en.wikipedia.org/wiki/X_Macro
"X Macro is a technique in the C and C++ programming languages for generating repeating code structures at compile time. It is used when the same operation has to be executed for a list of items, but regular for loopscannot be used.
Usage of X Macros dates back to 1960's.[1] It remains useful also in modern-day C and C++, but is nevertheless relatively unknown.[2] [3]"
"X Macro is a technique in the C and C++ programming languages for generating repeating code structures at compile time. It is used when the same operation has to be executed for a list of items, but regular for loopscannot be used.
Usage of X Macros dates back to 1960's.[1] It remains useful also in modern-day C and C++, but is nevertheless relatively unknown.[2] [3]"
Александр, возможно Вам будет интересно:
ОтветитьУдалитьhttp://en.nothingisreal.com/wiki/GPP
Я такое использую при сборке единого xml-документа по кусочкам из множества файлов.
Спасибо. Правда у меня есть "свои приборы" :-)
УдалитьСамое интересное по затронутой теме, обнаруженное мной за последнее время.
ОтветитьУдалитьОсновой посыл: можно сколько угодно "изгаляться" с собственным DSL для кодогенерации (m4, GPP и т.д.), но в сравнении с полноценным скрипт-языком это будет смотреться жалкой поделкой из 70-х.
Я утрирую конечно, но IMHO совершенно очевидно, что замена "макросов", которые разворачивает препроцессор на полноценные функции скрипт-языка даёт массу возможностей и снимает массу ограничений.
Не говоря уже о том, что криптованный синтаксис препроцессоров не идёт ни в какое сравнение с конструкциями полноценного языка программирования.
Кроме того, вот это:
«...Поскольку маркерные строки адаптированы под синтаксис любого языка, то маркеры могут скрыть Python-код генератора внутри исходного файла. Это означает, что Cog-файлы могут быть включены в базу контроля версий, и при этом не нужно беспокоиться о том, чтобы хранить отдельно исходный файл с генератором и результирующий выходной файл. Это также означает, что вам не нужно менять сложившуюся методику компиляции-сборки проекта и т.д.»
выглядит для меня несомненным преимуществом.
Т.е. шаблон и результат кодогенерации (тот файл, в который разворачиваются макросы в терминах препроцессора) могут быть, хотя и не обязательно, одним файлом.
Если формально применять Cog при сборке, обрабатываемый файл обновится только в случае, если после применения к нему генератора в нём что-то поменяется.
В общем - IMHO классная штука.
PS: Прошу считать всё сказанное выше личным IMHO ни на что не претендующего автора.
Красиво Вы пишете.
УдалитьЯ вот порой прокручиваю в голове сценарии, в которых представляю как макрос разворачивается в код, который потом будет исполняться... с сожалением, что в Delphi макросов (таких как в С) нет. (Удивительно, но буквально пару дней назад, т.е. незадолго до этого поста в блоге, снова думал над этой темой.)
И сэмулировать их красиво (без промежуточных файлов, т.е. так, чтобы сгенерированный код развернулся прям на месте и на лету) - не получается.
>> замена "макросов", которые разворачивает препроцессор на полноценные функции скрипт-языка даёт массу возможностей и снимает массу ограничений.
Вот это особенно понравилось. Но сразу подумалось - а как заниматься отладкой таких штук? Рано или поздно ведь придётся...
«...сэмулировать их красиво (без промежуточных файлов, т.е. так, чтобы сгенерированный код развернулся прям на месте и на лету) - не получается.»
Удалить-- У Cog (и его аналогов) есть возможность разворачивать "макрос" непосредственно в файл-источник (исходный код). Это позиционируется как одна из самых интересных "фишек".
Настроить применение cog к нужным файлам, думаю можно в IDE Delphi - вроде бы, такая возможность присутствует.
Не знаю уж, насколько это всё красиво, для меня кодогенерация - некое крайнее средство, применение которого мотивировано только там и тогда, когда иные подходы либо не работают, либо оказываются затратнее. Есть исключения конечно - например, генерации DDL-инструкций для генерации или преобразования БД в случае, если в другом источнике есть её метаописание. Но DDL скорее - ресурс, нежели программа, по сути представление меаданных в специфической форме.
Для настоящего программного кода (опять же IMHO) кодогенерация - инструмент для исправления пороков проектирования и/или недостатков, присущих языку.
Я понимаю, что всё это звучит несколько экстремистски, но за более чем 20 лет работы в области мне только недавно пришлось признать, что подход, основанный на генерации кода (а не на рефакторинге существующего) имеет право на жизнь. Основная причина в том, что не в моих силах всё переработать.
В своём проекте (надеюсь, хватит сил) я постараюсь продемонстрировать и мотивировать применение этого подхода.
«Вот это особенно понравилось. Но сразу подумалось - а как заниматься отладкой таких штук? Рано или поздно ведь придётся...»
Гм... Отлаживать код на Python не просто, а очень просто :-)
Есть PyCharm Free Community Edition, PyDev для Eclipse, масса сторонних инструментов, отладчик входит в инсталляционный комплект Python наконец.
Cog – это Python приложение, «макросы» на нём — функции на Python, размещённые в Python-модулях. Не вижу вообще никаких проблем с отладкой кодогенерации — ставите breakpoint в интересующем месте и смотрите, что и как работает.
Про трудности в отладке - я имел ввиду, если это попробовать применить к Delphi и её IDE.
УдалитьЗа остальное - спасибо, есть чего для себя пооткрывать.
«Про трудности в отладке - я имел ввиду, если это попробовать применить к Delphi и её IDE.
УдалитьЗа остальное - спасибо, есть чего для себя пооткрывать.»
-- Хм... Не уверен, что понял Вас правильно и в этот раз :-(
Код, который генерируется, он ведь получается на основе инструкций, размещённых в исходном тексте.
Не далее как минувшей ночью я развлекался с подмешиванием функциональности ED к произвольному классу. Т.е. реализовывал те самые mix-in-ы, симпатию к которым выражал Александр.
Поход который он демонстрировал, при том, что он безусловно рабочий, мне представляется несколько тяжеловесным. Альтернативный подход - использовать прямую кодогенерацию.
В модуле Python я разместил функцию, которая из двух строковых констант генерирует словарь, содержащий интерфейс и реализацию класса примеси посредством подстановки идентификатора класса предка и класса, код которого следует сформировать.
В исходном тексте указываются инструкции cog, обеспечивающие вызов функции, вывод в интерфейсной секции модуля интерфейсной части класса и, в секции реализации, соответственно - реализации класса примеси.
А дальше в исходном тексте - как у Александра: результирующий класс (к которому подмешиваем) получается наследованием от класса примеси.
Если интересно - исходный код я могу показать.
Изменяется оригинальный исходный текст, т.е. модуль Delphi, содержащий инструкции cog. Этот же модуль попадёт и под отладку, если в ней возникнет необходимость.
1. "кодогенерация - инструмент для исправления пороков проектирования и/или недостатков, присущих языку."
Удалить2. "мне только недавно пришлось признать, что подход, основанный на генерации кода (а не на рефакторинге существующего) имеет право на жизнь. Основная причина в том, что не в моих силах всё переработать."
-- полностью согласен
"В своём проекте"
Удалить-- как проект называется? Хочу ссылку опубликовать.
>>Не уверен, что понял Вас правильно и в этот раз :-(
УдалитьНу и ничего страшного :)
>> Если интересно - исходный код я могу показать
Да, это интересно
«"В своём проекте"
Удалить-- как проект называется? Хочу ссылку опубликовать.»
-- Александр, проект всё тот же Skydiver, я ссылался на него из статьи о расширенном делегировании.
В сущности, это набор адаптированных модулей (устранены все зависимости от несущественных внутрикорпоративных вещей, которые сложились исторически) которые у нас лежат в фундаменте разработки. Сама по себе ссылка на исходники мало что даст, поскольку я только что обнаружил, что не сподобился даже на readme к проекту, полностью положившись на две статьи, эту и эту.
Вообще, как мне показалось, тема интереса не вызвала. С одной стороны, я не пиарил материалы, обратился разве что на DelphiFeeds, но оттуда мне не ответили. С другой стороны, большинство разработчиков, использующих Delphi крайне трепетно относятся к исходным текстам RTL и VCL, и предложения внести в них изменения, пусть даже это много что даёт (что не очевидно из двух материалов) не находят у них понимания.
Вот я и подумал - а если бы "партия приказала" не вносить изменения в стандартные модули, как бы я стал выкручиваться? - Забавно было почувствовать себя в шкуре себя же, но в 2005-м году, когда я только взялся за дело :-)
Но в 2005-м я любую идею, связанную с дублированием кода просто не рассматривал. Уж лучше внести один раз изменения в стандартные модули. С другой стороны, без аппарата ED я не представлял себе приемлемую архитектуру приложения. Забавно также и то, что Cog в 2005-м уже был:-)
И я кстати, не знаю что из этого всего выйдет. Сейчас слишком серьёзная неопределённость относительно результатов, очень непросто предвидеть с какими проблемами придётся столкнуться далее, по мере появления сложных композитных объектов и множества их обработчиков.
Поэтому приходится заниматься всем этим самому и в свободное время, не имея уверенности в успехе привлекать людей в рабочее время я не имею морального права.
Но действительно интересно, что из этого всего выйдет.
Впрочем, если не получится, я по крайней мере пойму почему. В 2005-м я даже и не думал в этом направлении, почему бы не попробовать сейчас...
Хотя вот одно несколько сдерживает. Я в сущности, пытаюсь сделать то, что уже работает, но другим способом... :-)
"Вообще, как мне показалось, тема интереса не вызвала."
Удалить-- у меня - вызвала, правда у меня "есть свои приборы",но я "на ус - намотал".
Я не стал комментировать ваши посты - потому, что я сними "в принципе согласен". Я стараюсь "не придираться к запятым". А по сути - многое верно. (Не сочтите за "менторство)
"обратился разве что на DelphiFeeds"
Удалить-- я повторно переслал ваши ссылки на DelphiFeeds. Посмотрим.
"Поскольку маркерные строки адаптированы под синтаксис любого языка"
Удалить-- в "нашем генераторе" как раз "маркерные строки" и используются.. :-)
Может быть позже - подробнее напишу..
>криптованный синтаксис препроцессоров не идёт ни в какое сравнение с конструкциями полноценного языка программирования.
ОтветитьУдалитьЭто ещё вопрос что лучше - неизвестный язык общего назначения, или неизвестный дсл. Хотя python многие знают, так что вполне разумно.