Здравствуйте, varenikAA, Вы писали:
AA>Вроде как неплох AA>
А причем тут F#?
Провайдеры типов в F# это разновидность макросов. К системе типов это не имеет ни малейшего отношения. Меня интересует решение на типах в TypeScript ну и в С++.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
EP>>Какие гигабайты выхлопа? VD>Обычные. В выхлопных каталогах. Там формирвется море промежуточного говна. Мы в этот вопрос еще лет 10 назад разбирали.
Вот именно, слышал звон и не знаешь где он. Ты со Spirit небось перепутал.
Metaparse парсит строки в compile-time, результатом является compile-time значение/тип и никакого лишнего кода в объектных файлах. Можешь сам убедится — скопируй код примера калькулятора в coliru и посмотри что в .o файлах.
VD>Это делается страшными побочным эффектами. А в промежутке там формируются тонны шаблонных классов, которые порождают гигабайты временных файлов даже на примитвной грамматике, а компиляция идет неприлично долго.
Те ужасы о которых ты говоришь были лет десять назад, пока ещё не было variadic и constexpr.
EP>>Ну я уже выше привёл пример — там for — он по строке, и в compile-time. VD>Это слишком простой пример. Он не показывает достижим ли результат. Нужно чтобы на вход было нечто вроде: VD>... VD>Ну, то есть, чтобы код содержал разбор грамматики и построение по ней некоторого, заранее не определенного, кода зависящего от этой грамматики.
Ну видимо ты опять переводишь тему к задачам решаемым Spirit'ом — ну да, теперь его можно расширить и задавать грамматику в compile-time — только как это к примеру ТС относится?
EP>>В какой строке? Ты о чём? Metaparse пораждает парсеры compile-time строк, а не его граматика задаётся в compile-time строке, хотя если нужно, можно и граматику в строке задать VD>В строке переданной в качестве параметра. Пример я выше привел.
Ещё раз, Metaparse позволяет создавать compile-time парсеры, которые обрабатывают compile-time строки.
Откуда взялось требование что грамматика должна задаваться строкой? (да, это возможно, но что ты пытаешься конкретно показать?)
EP>>Кому должна? VD>Программисту. Вот макры так могут за милую душу. При этом код их реализации простой и эффективный. В результате порождается только код парсера, без гигабайт промежуточных классов, которые еще должен переварить оптимизатор.
Возьми пример калькулятора Metaprase, отключи оптимизацию -O0, сгенерируй объектник -c и посмотри на размер main.o, нет там никаких гигабайтов, как и нет никакого побочного кода.
VD>Я хочу иметь грамматические правила вроде: VD>
В коде metarpse задаётся семантическое действие, а у тебя и этого нет
EP>>>>Ну в примере TS выше, как я понял — вся база данных, включая все данные, задаётся в compile-time, что действительно не очень-то и нужно — так как если все данные уже есть в compile-time, к ним доступ через sql, да ещё и в compile-time не особо-то нужен. EP>>>>А вот приспособить это для типизированного доступа к БД а-ля SQL-macros — должно быть вполне реализуемо. VD>>>Вот обычно на этом и начинаются трудности, так как системы типов не особо приспособлены для доступа к внешним источникам данных. Для макры это не проблема, так она не не более чем программа запускаемая во время компиляции. А для приседания на типах — проблема. EP>>Речь не идёт о хождении в базу compile-time, речь идёт о генерации о проверки запросов compile-time, которые ходят в базу в runtime. Как linq2db, только, только без runtime-оверхеда. VD>Так нет никаких проверок в компалйтайм. И базы нет. Есть самопальная БД на типах и хождение к ней. Ты хотя бы в коде разобрался бы. Нам на входе списки описанные на типах, а на выходе типы описывающие списки. Чистый сфероконо, который не применим на практике. Там в типах обрабатываются данные.
Ты читать видимо не умеешь, или контекст не удерживаешь, так как я выше тебе уже выше объяснил что именно делает пример ТС.
А типобезопасный доступ к БД — это как пример где это могло бы реально быть применимо. Забавно что в следующем
EP>>>>Ну в примере TS выше, как я понял — вся база данных, включая все данные, задаётся в compile-time, что действительно не очень-то и нужно — так как если все данные уже есть в compile-time, к ним доступ через sql, да ещё и в compile-time не особо-то нужен.
EP>>>>А вот приспособить это для типизированного доступа к БД а-ля SQL-macros — должно быть вполне реализуемо.
EP>>Первое — давно возможно. Доступ к строкам в compile-time есть, полный по-тьюрингу язык для их обработки тоже есть, причём не один. VD>Ну, значит покажи примитивный пример (я не прошу полный парсер-генератор), который бы разобрал строку и построил по ней функцию разбирающую грамматику в этой строке.
Я не пойму откуда взялось требование о том что грамматика должна задаваться строкой.
Разбор compile-time строк ты уже увидел. О тьюринг полноте шаблонов ты знаешь. О тьюринг-полноте constexpr функий можешь загуглить в один клик. Что конкретно интересует-то?
EP>>Второе — нет, так как нет API для доступа к DB, чтению файлов и т.п. Но для таких редких use-case'ов внешнюю кодогенерацию не в лом использовать. Ну то есть например нормальный макросы — да, хотелось бы. Доступ к DB в compile-time — не особо VD>Ага. Это как в классическом: Не дает, ну и не очень то и хотелось! (ц) VD>Нормальные макры тупо не имеют таких ограничений. Это просто код — плагин к компилятору, который может читать любые данные (включая код проекта) и порождать новый. При этом у него нет проблем прочитать и метаданные из внешней БД, например. VD>Вот представь себе, что вместо: VD>... VD>expr — это твой литерал. Вот это и есть макрос о котором я говорю. В другом макросе в строке может быть передан URI БД. И мы просто сходим туда во время компиляции и прочтем от туда метаданные, по которым скомпилируем функции доступа к ней.
Макросы в Лиспе использую постоянно. Нормальные макросы в C++ очень хотелось бы, да. Даже хотелось бы макросов в Python'е, именно поэтому смотрю на Hylang.
Доступ к БД во время компиляции — как-то без энтузиазма — конкретно для этой задачи не в лом добавить правило кодогенерации в систему сборки Причём если ходить в базу из макросов, то всё равно придётся информировать систему сборки о том что результат компиляции вот этого TU зависит не только от кода
Твои многочасовые презентации по Nemerle я смотрел — представляю как он работает, знаю что умеет, многим впечатлён Убеждать меня в его преимуществах не нужно, я уже убеждён.
По моему мнению вы промахнулись с целевой платформой и аудиторией. Вот если бы вместо .NET вы генерировали C++, или даже C (как Страуструп когда-то), то получили бы охват всех платформ, и целевую аудиторию которой не в лом создавать и использовать штуки типа Spirit, MetaParse, Hana и т.п., несмотря на все трудности сопряжённые с этим.
Здравствуйте, varenikAA, Вы писали:
AA>Не то? Значит я ошибся.
Я уже ответил же. F# пользуется провадерами типов, которые по сути являются видом макросов.
AA>Вроде в ТС таже задача — генерация типов по схеме и тестовым значениям.
ТС демонстрировал нечто реализованное на базе системы типов TypeScript. Но это сфероконь, так как там и БД в системе типов описана, и результаты запросов в виде типов получатся. К генерации кода оно отношение не имеет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
I>>Это именно игрушка, показывает возможности системы типов.
VD>Ну, вот оно конечно прикольно, но практического смысла не имеет.
Ты повторил своё утверждение, хотя я привел тебе практический пример. Такими завален чуть не весь интернет.
VD>Интересно было бы узнать можно ли сделать таким образом именно типизированный доступ к БД? Ну, чтобы я мог описать метаданные БД, а потом в строках писать запросы, а они не только бы проверялисть на корректнось, но еще и генерился бы код выполняющий запросы и возвращющий результаты в типизированном виде.
Нет, нельзя. И слава богу, что нельзя. Тайпскрипт целенаправленно идет другим путём — легковесные типы, которые ничего не стоят в рантайме. Это делается для того, что бы не было расхождения с JS. Все языки, которые наяривают свои "фишки", уверенно тонут, как только в JS добавляются новые фичи. Это случается, кстати, очень часто.
Здравствуйте, VladD2, Вы писали:
VD>Ну, вот оно конечно прикольно, но практического смысла не имеет.
Ты просто не понимаешь что такое TS и для чего он нужен.
1) TS это динамически типизированный язык с опциональной статической типизацией
2) TS на 100% совместим с JS
3) До сих пор оченьбольшое количество популярных библиотек пишется на JS
4) Естественно, в большинстве случаев никто не заморачивается при их написании с тем, чтобы оно легко ложилось на систему типов TS
5) Основное назначение TS — прежде всего типизировать существующие библиотеки. Отсюда и такая навороченная система типов, призванная по максимуму вытащить статические данные из причудливых изначально динамических API JSных либ.
Здравствуйте, Evgeny.Panasyuk, Вы писали: EP>Речь не идёт о хождении в базу compile-time, речь идёт о генерации о проверки запросов compile-time, которые ходят в базу в runtime. Как linq2db, только, только без runtime-оверхеда.
Можешь привести пример полезного кода с этим запросом?
Не такого, чтобы результат смотреть как всплывающую подсказку под мышиным курсором, а чтобы было это: сгенерило entity тип по данной строке
сгенерило текст SQL запроса
Чтобы как-то так:
type MyQuery = Query<"select firstName, lastName from users where isActive == :isActive">;
type NamesEntity = Entity<MyQuery>;
let params: QueryParams<MyQuery> = {
isActive: true
};
const sqlQuery = GetSqlQueryOf<MyQuery>();
const queryResults = ExecuteQuery<NamesEntity>(sqlQuery, params);
for (let i = 0; i < queryResults.length; ++i) {
console.log(`{i}. {queryResults[i]}`);
}
Здравствуйте, alexanderfedin, Вы писали:
EP>>Речь не идёт о хождении в базу compile-time, речь идёт о генерации о проверки запросов compile-time, которые ходят в базу в runtime. Как linq2db, только, только без runtime-оверхеда. A>Можешь привести пример полезного кода с этим запросом?
пример. По EDSL запросу генерируется тип результата, текст SQL запроса, и эффективный доступ к результату, всё в copmile-time. Далее там показывается как бы это выглядило вручную. Результирующий ASM в обоих вариантах идентичен.
Единственное отличие от твоего примера в том что запрос задаётся не строчкой, а как expression template. Но я уже показывал в теме что и строчки можно обрабатывать в compile-time, так что если хочется именно строчкой (не думаю что это лучший вариант), то можно задать вопрос и строчкой, и будет тот же самый результат.