Обновить
4K+
7
Иван@Adler3D

TOP3 на «codingame::contests::ru»

5
Рейтинг
4
Подписчики
Отправить сообщение

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

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

Odin

посмотрел их компилятор и примеры, интересная штука. парсинг вручную делают на С++. обмазались макросами в заголовочнике и довольные ходят. а ещё у них eval-а нет. а без него ЯП делать сейчас — это большая ошибка как мне кажется.

Насколько я понял вы берёте некоторый код, прогоняете его сквозь свой фронт и не выходе получаете некоторое собственное представление AST

На выходе пока обычный JSON, и дальше он никуда(ну кроме как на проверку глазами) не идёт, хотя может в теории, но загонять его ещё куда-то мало смысла как по мне, т.к весь смысл в том чтобы обходить дерево из которого он строится прямо на стороне С++ — это красиво/удобно/мощно/всё_собственно_для_этого_и_делается.

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

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

Вот этот шаг от обработки через ваш фронт и до этапа когда оно попадает в компилятор я и назвал генерацией

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

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

вот это я опять не понимаю что вы тут имеете ввиду: какой ещё аналогичный код? о каком коде речь? да ещё и ручками? единственное что приходит на ум когда мне говорят что я что-то не пишу ручками — это выхлоп от генератора парсеров, но причём тут он?

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

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

модули (module, import, export), ничего связанного с корутинами (co_await, co_yield etc)

модулей пока действительно нет и co_yield тоже нет, а вот co_await есть/поддерживается, правда в статье не упомянут, его надо в грамматике(в файле inp.qapdsl.h) смотреть.

consteval упомянут в скрипте в часть 1, но похоже тоже нигде больше не участвует. constinit туда же

consteval и constinit просто добавлены в списки ключевых слов, но я тщательно не проверял их работоспособность во всех контекстах.

всякие [[аттрибуты]] не замечены

аттрибуты должны вроде полностью поддерживаться, смотрите файл inp.qapdsl.h#L95

explicit(bool)

интересный зверь.

синтаксис рефлексии и синтаксис контрактов - тоже не видны

рефлексии пока нет, добавил про это в статью, а вот контракты я очень сильно старался сделать полностью, но всё равно нашлись 20% сценариев где они не парсятся пока.

не очень понятно зачем вы целое одно предложение под спойлер спрятали. У вас в том файле кодировка сползла и похоже часть текста в windows-1251.

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

У вас в том файле кодировка сползла и похоже часть текста в windows-1251.

так и есть. сейчас пойду править.

Проинстанцируйте в сгенерированном коде ещё и шаблоны и скорость компиляции вырастет ещё больше

наоборот же должно быть? когда это от инстанцирования шаблонов скорость компиляции росла?

Умудритесь вычислить лексически все constexpr/consteval - получите ещё плюс

хм, заманчивое предложение, попробую.

Ну и можно поэкономить на спичках убрав всякие public: public:

ха, вот это баг, там между ними объявления полей должно быть, но я не тот файл подложил когда "cl /EP" вызывал и в итоге во всём файле поля внутри сериализуемых структур отсутствуют. забавно. нужен план как это пофиксить... обновить и файл и результаты его парсинга в статье что-ли? да, наверно так и надо сделать. спасибо за находку!

А вообще стоило бы замерить сколько времени занимает генерация и сравнить с компиляцие того же файла без генерации.

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

спасибо за ценный комментарий!

можно ли эту штуку применить в малом бизнесе?

тоже стало интересно и тут меня тоже на этой теме понесло в далёкие края: https://gamedev.ru/flame/forum/?id=294016

А у вас я сходу такое не нашёл.

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

struct t_node_base{int start=-1,end=-1;};

и далее все лексеры наследуются от этой базы.

Если нужна эта фишка поскорее - пишите, выложу.

очень много строковых операций

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

заходит подход через описание всех токенов в enum, ближе к низкому уровню.

Да, я умышленно в этом месте пожертвовал скоростью ради удобства + теперь не могу заводить токены и enum`ы :)

Надеюсь когда-то смогу за счёт красивой архитектуры автоматически подменять строки на токены/enum в коде, но пока эта идея из области фантастики.

PS: Процитированный вами код - это не сгенерированный код, а вручную написанный код для обхода полученного AST, но посыл/вывод полностью верный.

ближе к низкому уровню

Надеюсь вам/всем когда-то надоест эта близость с железом и вы продадите её временно ради удобства и мы вместе сделаем ещё что-то толковое.

Мне больше по душе свобода действий

Если вдруг кому-то/вам надоест писать парсеры вручную и захочется делегировать/разделить эту задачу с кем-то, то пишите мне я попробую помочь сделать эту часть работы на 5+(в плане архитектуры строготипизированного AST).

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

Что думаете насчёт того чтобы использовать готовый генератор парсеров который на выходе сразу даст вам строготипизированное AST на C++?

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

Вы кажется не поняли аналогию. Достижение некоторого НОВОГО знания будет пупыркой, которая закономерно строилась на основе каких-то предыдущих знаний.

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

В ПО всё обычно сводится к оптимизации последовательностей map/reduce.
...
Вот где-то между двумя этими крайностями и приходится лавироват, чтобы получать прибыль и развиваться

Очень интересная точка зрения, никогда о таком не задумывался, спасибо, теперь моя мрачная версия картины мира пополнится ещё и этим ограничением/знанием.

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

Про майнинг крипы даже не думал пока писал статью.


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


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

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

Оператор typeinfo обеспечивает инспекцию типов

Простого typeinfo из Ü/С++ пока недостаточно, т.к они например не захватывают информацию о выражении которым инициализируются поля структур/классов.

Вот если бы Ü был дружелюбен для разработки достойной системы сериализации/RTTI/толковых_умных_указателей/генерации_парсеров и на нём можно было повторить например разработку такой истории как тут, то тогда было бы понятно как переманивать программистов с других языков программирования.

Сделал статью "что-то вроде минимального примера" как вы просили: https://habr.com/ru/articles/978216/

Пойдёт?

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

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

почему до сего дня производства повально не автоматизированы?

наверно потому что тот кто ответственен за повальную автоматизацию пока не видит в этом смысла/профита. да и зачем спешить? можно дать всем шанс автоматизировать всё самостоятельно, а не насильно. если интересно вот чуть больше инфы по теме(там два сообщения от меня и два от ИИ): https://chat.deepseek.com/share/hexvsm55d4xueez6mh

ИИ подсказывает что вы хотите узнать зачем вам вообще мигрировать типы, если можно описывать всё через таблицы и каждый раз собирать сцену заново? То есть вы предлагаете перейти на декларативную сборку сцены тому кто занимается задачей "миграцией долгоживущего состояния сцены + эволюции типов"? Если так то спасибо за идею, но мне мой подход больше нравится. почему/зачем я так делаю/сделал? - потому что раньше мне казалось что это путь к идеальной архитектуре программ, а перестирать сцену каждый раз - это слишком простой/слабый/тупиковый путь. сейчас я менее категоричен и вижу плюсы обоих подходов и думаю что будущее за гибридным решением.

попросил ИИ перевести на понятный мне язык, вот его цитата:

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

  1. представить как байткод

  2. патчить

  3. при желании транслировать в нативный код

Но для этого придётся сделать язык + VM + транслятор,
то есть фактически DSL, а не просто сериализацию данных.
Это сложно, похоже на изобретение велосипеда,
но в итоге можно получить мощный комплекс отладки и патчинга.»

интерпретация от ИИ:

Он согласился с тобой, но:

  • не может выйти из парадигмы «всё = код»

  • поэтому постоянно тянет разговор к VM / DSL / байткоду

Ты же работаешь в другой оси:

  • данные эволюционируют

  • код остаётся нативным

Он этого ментально не различает.

вот что я думаю читая это:

что бы я сделал если бы нашёл кого-то кто про финансирует open-source разработку? - свой язык программирования который сразу без танцев с макросами и шаблонами понимает мою систему RTTI/STTI/указатели и при миграции между форматами генерирует настоящий нативный код для сохранения и загрузки состояния в этом новом формате, плюс ещё если к этому добавить safe_eval+unsafe_eval, то вообще было бы шикарно.

мы здесь не сериализуем некоторые вещи связанные с выполнением программы, а именно:
не сохраняем стек вызовов
не сохраняем PC / позицию выполнения
не трогаем низкоуровневые детали вроде сетевых или GPU-состояний

мы тут сериализуем почти всё состояние данных, включая ссылки и типы, чтобы:
обновлять бинарь
мигрировать структуры
продолжать работу без VM

VM/JIT решают другую задачу - управление кодом, а не миграцию данных между версиями типов.

для этого придумали скриптование. делаете какой-нибудь ctrl+r и триггерите переинициализацию скрипта. hotreload никогда не требовал сериализации графа.

Ну чистая правда, даже придраться не к чему. Хотя есть: скрипты - это иногда медленно; структуры данных внутри скриптов также может меняться и ломать миграцию молча и противно. Можно попробовать парировать отсылкой к JSON-based системам миграции, но это опять же медленно и не лишено кучи недостатков.

заводите класс реестра ресурсов и просто ссылаетесь на ресурс по некоторому составному id - resource id + offset id. В качестве resource id можно взять например djb2 хэш от пути к ресурсу. Offset id зависит от того как вы получаете конкретный элемент в ресурсе. Пару широких интов определённо проще сериализовать чем возиться со ссылочными типами, которым ещё некоторую персистентность надо навести.

100% правда. я так поступил из-за своего неумения проектировать программы. я даже не могу возразить что у меня есть плюс - типа мои ссылки быстрее работают, а вот нифига, id+hash рулят и педалят походу. Всё что меня спасает - это отсутствие коллизии хэшей вообще.

Так а используется-то оно как? Выглядит как несколько странный дебаггинг, судя по вашему описанию.

Используется при миграции между форматами.

Ну, вы же решали какую-то свою боль, изобретая вот это вот всё.

ну я научился сохранять всё состояние программы со всеми ссылками и метаинфой, получил крутую миграцию. боль была в том, что предыдущая система сериализации не умела сохранять обычные не полиморфные типы данных. А это очень полезно для работы по сети, т.к там требуется компактность и скорость. В скорости я проиграл из-за того что интерпретирую метаинформацию при обходе дерева/графа, а вот компактность получил. Правда для сети мне оказались ссылки не нужны и поэтому я сделал ещё одну версию сериализатора без них. И она победила из-за своей скорости компиляции.

Сделайте минимально воспроизводимую боль. Пусть без окон и imgui крутилок, но понятную другим.

ИИ подсказывает что можно сделать демонстрацию профита от моей системы на примере системы из publisher-subscriber и их миграции в новый формат. Попробую сделать. Спасибо за то что навели на хорошую идею примера!

Информация

В рейтинге
1 343-й
Зарегистрирован
Активность

Специализация

Десктоп разработчик, Разработчик игр
От 231 456 ₽
C++
Node.js
JavaScript