Здравствуйте, Pzz, Вы писали:
Pzz>Я думаю, дело не в полноценности-неполноценности. Эта-то проблема давно решается с помощью древней, как UNIX System 7, парадигмы автоматической генерации кода во время сборки с помощью специально написанных для этой цели программ или скриптов.
Не совсем согласен. Я тоже богатею думкой на досуге и про этот нюанс думал. И даже порывался несколько раз создать тему и описать свои мысли, но пока себя сдерживаю.
Я согласен с тем, что считаю создание второго языка для метапрограммирования ошибкой. Которую делают многие языки. С++, Scheme, Rust из тех, которые я знаю. Хотя Scheme и Rust хотя бы спроектировали этот язык намеренно, а не случайно...
Но не согласен с тем, что это лучше делать отдельной программой. Метапрограммирование лучше бы делать на том же языке, как часть проекта (или библиотеки). Просто запускать обычный код во время компиляции. Чем это лучше тупо отдельной программы? А вот чем:
1. Компилятор имеет доступ к AST, т.е. может дать мета-функции на вход уже распарсенное AST. Это удобно и это быстро.
2. Мета-функция может на выходе конструировать опять же AST, а не текст программы в виде строки. Это удобно и это быстро.
3. IDE может запускать мета-функцию в фоновом режиме и использовать её результаты для семантической подсветки и прочего вспомогательного функционала.
Всё, что нужно от самого языка это предоставить удобные средства работы с полиморфными деревьями. В первую очередь это типы данных из тех, что называют алгебраическими, во вторую очередь это паттерн-матчинг. Но это всё в современных языках идёт "по умолчанию", как правило.
А минус вижу только один, это та самая IDE. Ничего не мешает в мета-функции, к примеру, подключаться к БД, вытаскивать её схему, генерировать классы на основе таблиц и возвращать их в виде AST. Как такое поддерживать в IDE, я не представляю. Нужно очень хорошо продумывать, как реализовывать кеширование в ожидаемом для юзера виде, видимо. Ну или кастрировать эти мета-функции, запрещая им подключаться к БД, ограничивая время их выполнения, но это, конечно, совсем не так интересно...
Немного в тему пример это D. Там есть две фичи: во-первых compile-time функции (тут ничего интересного, по сути аналогично C++), но эти функции могут возвращать строки. А также там есть конструкция, позволяющая эту compile-time строку включить в программу. И вот как раз это позволяет делать то, что я описал, правда без AST. К примеру моей ненаписанной дипломной работой была интеграция лиспа в D, когда можно было бы писать код на лиспе, перемежая его с кодом на D, вызывая друг друга и это всё в одном файле, в одной программе, без извращений с синтаксисом (код на лиспе в компайл-тайме транслировался бы в эквивалентный код на D). В целом там всё было реализуемо.