LINUX.ORG.RU

Зачем нужно метапрограммирование?

 ,


2

1

Имеются ввиду возможности, встроенные в сам язык. Что имеем:

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

Зачем нужна такая фича, когда можно генерировать код внешней утилитой?

Ты наверное удивишься, но метапрограммирование зачастую и реализуется через кодоген, так как это и есть его суть, какая разница внутри языка этот кодоген функционал или внешним приложением?

anonymous
()

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

Aswed ★★★★★
()

Зачем нужно программирование, если программы можно генерить метапрограммами?

anonymous
()
Ответ на: комментарий от anonymous

Метапрограммирование не просто реализуется через кодоген, а это он и есть.

какая разница внутри языка этот кодоген функционал или внешним приложением?

Я ж описал недостатки в оп. Если иметь в языке, например, unsafe блоки, где метапрограммирование разрешено(соответственно, контексты явно разделены) - то разницы практически никакой. Только остаётся вопрос, нафига это было в язык переть, кто-то add_custom_command() в сборке заюзать не осилил что-ли?

cppsektant
() автор топика
Ответ на: комментарий от crutch_master

Копипаст с метапрограммированием слабо связан. Да и опять же, внешний кодоген решает

cppsektant
() автор топика

cppsektant

пацаны, расходимся, он погряз во грехе и благость Метапрога не узрит

anonymous
()
Ответ на: комментарий от Aswed

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

cppsektant
() автор топика
Ответ на: комментарий от anonymous

Вообще-то, их так и генерят. Только метапрограммами это никто не называет, обычто говорят «транслятор» или «компилятор»

cppsektant
() автор топика

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

anonymous
()

ресурсы на сборку приложения превышают таковые для его запуска(иногда многократно)

генерировать код внешней утилитой?

А ресурсы на генерацию внешней утилитой ты не включаешь в ресурсы на сборку приложения?

chkalov
()
Последнее исправление: chkalov (всего исправлений: 1)

сильное усложнение языка(с т. з. кодера)

Почему всех должны волновать проблемы макак?

большая свобода действий для кодера, что, как известно, губительно в коммерческих(да и не только) проектах

Почему все должны ориентироваться на коммерческие (и не только) проекты, где тебя принято держать за макаку?

ресурсы на сборку приложения превышают таковые для его запуска(иногда многократно)

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

сложность реализации компилятора, приводящая к ошибкам

Тебе шашечки, или ехать?

Зачем нужна такая фича, когда можно генерировать код внешней утилитой?

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

Siborgium ★★★★★
()
Ответ на: комментарий от cppsektant

Очевидно что это неубедительные недостатки, думаешь внешний кодоген для сложного языка будет проще в реализации чем тот что уже языке? Странно так думать, ведь это две одинаковые задачи.

anonymous
()
Ответ на: комментарий от chkalov

Это незачем делать. Сначала работает кодоген, затем - компилятор. Очевидно, что кодоген потребляет намного меньше ресурсов, чем оптимизирующий компилятор

cppsektant
() автор топика
Ответ на: комментарий от cppsektant

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

anonymous
()
Ответ на: комментарий от cppsektant

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

Сразу отмечу, что под кодогеном в твоей терминологии понимаем компилятор из метаязыка в язык, под компилятором – компилятор в целевой код.

Siborgium ★★★★★
()
Ответ на: комментарий от cppsektant

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

chkalov
()
Ответ на: комментарий от Siborgium

Почему всех должны волновать проблемы макак?

Ты считаешь усложнение языка без какой-либо причины оправданным?

Почему все должны ориентироваться на коммерческие (и не только) проекты, где тебя принято держать за макаку?

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

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

С кодогеном точно так же. Только нет нужды иметь 32Gib рамы для сборки. Чему ты противоречишь?

Тебе шашечки, или ехать?

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

утилитку прикручивать к компилятору сложнее, чем реализовать функционал в компиляторе

Зачем её прикручивать к компилятору? Ты оп внимательно читал? Её к сборке надо прикручивать, лол.

Какой-то ты поехавший. Я тебя затриггерил чем-то что-ли?

cppsektant
() автор топика
Ответ на: комментарий от cppsektant

Это незачем делать.

Ты обделался, снова. Сначала работает парсер языка, который выцепляет из него некую мета-информацию, на базе которой уже будет производится генерация. Далее генерируется код. И далее он опять парситься и тот и тот.

Никакой «оптимизирующий компилятор» тут вообще не при делах. Кодогенерация любого вида работает на уровне выше.

Как работает встроенная в язык кодогенерация. Во-первых она парсит код один раз. Далее внутри себя генерирует код, не текстом, который потом нужно разбираться - а на уровне того же ast. И всё, есть уже готовое ast.

Тоже самое на кодогене дерьма - это парсинг(оригинального кода) -> ast -> кодогенерация -> парсинг и оригинала и сгенерированной лапшли -> ast

Я думаю, даже подобный тебе дошколёнок поймёт, что лучше.

tosol4152
()
Ответ на: комментарий от chkalov

Нет. Я ж говорю, сначала одно отрабатывает, потом другое. Всё, никакой суммы

cppsektant
() автор топика
Ответ на: комментарий от anonymous

Нет не расходимся, а зовем сюда своих друзей.

anonymous
()
Ответ на: комментарий от Siborgium

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

Примеры?

cppsektant
() автор топика

Зачем нужна такая фича, когда можно генерировать код внешней утилитой?

В некоторых задачах удобнее внешняя утилита. В некоторых средства ЯП. Скажем std::vector для каждого Т внешней утилитой делать запаришься.

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

AntonI ★★★★★
()
Ответ на: комментарий от cppsektant

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

Отказ от ответственности.

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

anonymous
()
Ответ на: комментарий от Siborgium

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

Любая программа. Кодоген по определению медленней. Обратные примеры не могут существовать.

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

Вычислений там в принципе нет. К тому же именно вычисления могут стать проблемой. Ведь если колхозник напишет вычисление какого-либо факториала в кодогене - код будет скомпилирован.

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

tosol4152
()
Ответ на: комментарий от anonymous

Это как и написали ранее зависит исключительно от того, кто и что понимает под метапрограммированием, и кто и как его реализует

Справедливости ради - да, есть такая неоднозначность.

cppsektant
() автор топика
Ответ на: комментарий от cppsektant

Вообще то есть мнение что плюсовые шаблоны это один из примеров метапрограммирования. Но я не буду спорить.

AntonI ★★★★★
()
Ответ на: комментарий от cppsektant

Можно небольшой пример?

Нет.

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

И, вообще, оригинальная фон-Неймановская архитектура поощеряла (не запрещала) изменение кода программы самой программой. Но кому нужны оригиналы, а нас свой путь с раздельными очередями (вместо произвольного доступа) команд и данных, зато с мельтдаунами, спектрами и кольцами -2 уровня.

anonymous
()
Ответ на: комментарий от cppsektant

Ты считаешь усложнение языка без какой-либо причины оправданным?

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

там будет та же самая проблема

Я не знаю ни одного проекта на языке с дженериками, где были бы запрещены дженерики.

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

Я не знаю ни одного проекта на языке с тайпклассами, где было бы запрещено использование тайпклассов.

Все эти инструменты языка можно называть средствами метапрограммирования. Продолжать перечисление?

С кодогеном точно так же. Только нет нужды иметь 32Gib рамы для сборки. Чему ты противоречишь?

Что за чушь ты несешь? Какие 32Gib, какая сборка, какой кодоген? Я тебе отвечаю на вопрос о том, почему «кодоген» имеет смысл. Даже в каком-то гипотетическом языке и каком-то компиляторе, где конкретный способ метапрограммирования реализован настолько плохо и/или проект настолько большой, что тратит пусть даже 256GiB, это все еще имеет смысл.

не огораживать проблемный(из-за ошибок компилятора) код костылями

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

Зачем её прикручивать к компилятору? Ты оп внимательно читал? Её к сборке надо прикручивать, лол.

Еще раз. Хотя утилитка прикручивается к сборке, этой утилитке (если это не примитивный препроцессор) потребуется AST-дерево. Компилятор, как минимум, должен будет ей выдать это дерево, чтобы утилитка могла его изменить и скормить обратно компилятору, который из него создаст целевой код. Таким образом, она будет непосредственно привязана к репрезентации AST-дерева компилятором.

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

Siborgium ★★★★★
()
Ответ на: комментарий от anonymous

программу меняют программой, и хрен поймешь где там мета, а где сама программа

Вот это самый, наверное, весомый аргумент против меты в языке

cppsektant
() автор топика
Ответ на: комментарий от tosol4152

Вычислений там в принципе нет. К тому же именно вычисления могут стать проблемой.

Чего?

напишет вычисление какого-либо факториала в кодогене - код будет скомпилирован.

Напишет, и не один, а 100 факториалов, и без мемоизации. Кодоген (во все той же терминологии) займет 5 минут на вычисление факториалов а компиляция результата в бинарь – 5 секунд.

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

Чего?

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

Напишет, и не один, а 100 факториалов, и без мемоизации. Кодоген (во все той же терминологии) займет 5 минут на вычисление факториалов а компиляция результата в бинарь – 5 секунд.

Ты всё перепутал. В компиляцию уже должны быть включены результаты вычислений этого факториала. На то это и компилтайм-вычисления.

Поэтому внешний кодоген сгенерирует таблицу факториалов быстрее(вероятно), чем внутренний. Просто потому, что вычисляет факториалы быстрее.

tosol4152
()
Ответ на: комментарий от Siborgium

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

Оно не оправданное - внешний кодоген решает задачи генерации кода. Примеры хоть давай.

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

Ты ничего не ответил.

Еще раз. Хотя утилитка прикручивается к сборке, этой утилитке (если это не примитивный препроцессор) потребуется AST-дерево

Ещё раз, последний. Утилита генерирует код на целевом языке, никакие аст ей не нужны.

Какие 32Gib, какая сборка, какой кодоген?

Что-то слигком много вопросов от тебя, причём о тривиальных вещах. Ты точно программист?

Я не знаю
Я не знаю
Я не знаю
Продолжать перечисление?

Да нет, не стоит. Всё равно по теме тебе сказать нечего окромя пассажей про макак

cppsektant
() автор топика
Ответ на: комментарий от cppsektant

программу меняют программой

весомый аргумент против меты в языке

А почему не за? «Ты ж программист», а не писатель детективов линейным сюжетом.

anonymous
()
Ответ на: комментарий от anonymous

А почему не за? «Ты ж программист», а не писатель детективов линейным сюжетом

это тебе к Siborgium, он там выше про макак что-то затирал. Вероятно, что «писатель детективов» == «макака».

cppsektant
() автор топика
Ответ на: комментарий от Siborgium

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

Нет, утилиты так не работают. О чём я тебе уже говорил выше. Двунаправленная передача данных - это только внутренняя кодогенерация, т.е. с общим ast.

Внешняя же - однонаправленная. оригинал -> ast -> кодогенерация -> дополнение -> (оригинал + дополнение) -> ast -> целевой код

tosol4152
()

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

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

Lzzz
()
Ответ на: комментарий от cppsektant

Ты ничего не ответил.

Какой вопрос, такой и ответ.

Утилита генерирует код на целевом языке, никакие аст ей не нужны.

Примеры хоть давай

Отвечу сразу на оба вопроса, дав пример простой, утилитарной вещи, которую ты не реализуешь без AST-дерева – сериализация-десериализация структур.

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

Вот на этом моменте ты и начинаешь заниматься шашечками вместо езды. И упорно продолжаешь, в конце концов реализуя свой компилятор. Тебе буквально придется реализовать гигиенические макросы, чтобы заменять type на int, когда type это тип, и ничего трогать, когда это имя переменной. А для этого тебе уже нужно будет как минимум правильно разбирать код на токены.

Ты точно программист?

А ты точно понимаешь, о чем говоришь? Ты пишешь бред, но в непонимании тривиальных вещей упрекаешь меня. Кстати, когда человек говорит о чем-то тривиальном, то, временами, именно это он понимает хуже всего. Возьми себе на заметку.

Siborgium ★★★★★
()
Ответ на: комментарий от tosol4152

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

Siborgium ★★★★★
()
Ответ на: комментарий от cppsektant

Еще раз повторю. Сложное можно описать только сложным (пока вроде не доказали P=NP). И хорошо, если получается сложность спрятать за простыми на вид мета-конструкциями. В общем, не всех удовлетворяют детективы с линейными сюжетами.

anonymous
()
Ответ на: комментарий от Siborgium

Какой вопрос, такой и ответ.

Кто ж так открыто сливается.

Отвечу сразу на оба вопроса, дав пример простой, утилитарной вещи, которую ты не реализуешь без AST-дерева – сериализация-десериализация структур

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

cppsektant
() автор топика
Ответ на: комментарий от anonymous

не всех удовлетворяют

Не буду спорить - да, иногда это действительно нужно. Про крайние случаи я не подумал

cppsektant
() автор топика
Ответ на: комментарий от Siborgium

Ну да. Я про то, что утилитка не может править ast.

А так да, причём ему нужен будет не только парсер, но и кодогенератор. Потому как если язык или задачи сложнее убожества - генерировать код текстом не вариант.

Но проблема не в этом. У него другая проблема. Он противопоставляет написание мета-программ готовой кодогенерации. Т.е. противопоставляет «делать» и «сделано» и сообщает, что «делать» сложно. Это базовая болезнью дошколят.

Т.е. если у тебя есть кодогенератор - у тебя есть готовая мета-программа. Но дошколёнок этого не понимает. А если её нет - нету и кодогенератора. Но дошколёнок предлагает что-то там подключать, подключать то, чего нет.

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

tosol4152
()
Ответ на: комментарий от cppsektant

Реализуется даже на сишных макросах, лол

А с тайпчеком осилишь на макросах? А с проверкой на возможность сериализовать член-данные? Приседания со штангой наподобие прописывания всего руками перед каждым полем не считаются.

В Boost’е-то и не знали, оказывается.

Кто ж так открыто сливается.

Это троллинг тупостью?

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

А с тайпчеком осилишь на макросах?

Что ты называешь тайпчеком?

А с проверкой на возможность сериализовать член-данные?

А имеет смысл делать по-другому?

Это троллинг тупостью?

Я не могу читать твои мысли, откуда мне знать?

cppsektant
() автор топика
Ответ на: комментарий от cppsektant

Реализуется даже на сишных макросах, лол.

Не реализуется. Показывай.

К тому же, проблема не в том, что делается - проблема в том как делается. Каково качество результата и каково качество процесса.

tosol4152
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.