Здравствуйте, Erop, Вы писали:
E>>>Что бы описать структуру с несколькими полями, предлагается выводиться из всех таких структур? Или какая идея? EP>>Наследование от всех таких структур EP>>
Со стороны пользователя вполне удобно, используется например в sqlpp11:
for (const auto& row : db(select(foo.name, foo.hasFun).from(foo).where(foo.id > 17 and foo.name.like("%bar%"))))
{
if (row.name.is_null())
std::cerr << "name is null, will convert to empty string" << std::endl;
std::string name = row .name; // string-like fields are implicitly convertible to stringbool hasFun = row.hasFun; // bool fields are implicitly convertible to bool
}
Ты можешь придумать более удобный синтаксис?
А со стороны реализации тоже проблем нет — есть же variadic templates
E>На самом деле, в С++ есть какой-то системный косяк уже давно с метапрограммированием.
Обсуждаемый контекст относится скорее к reflection и reification. Хотя да, с метопрограммированием связан.
E>Если уж развивать язык в эту сторону, то я бы лучше концепцию constexpr развивал. Всё равно у нас для реализации constexpr компилятор должен уметь исполнять CT с++ код без побочных эффектов, так что недалеко до того, что бы сделать так, что бы компилятор отдавал в макрос текст или АСТ или что-то вроде того, и получал наружу модифицированное тоже самое...
Да, было бы хорошо, вот только этого даже на горизонте не видно.
И к тому же думаю метапрограммирование на уровне AST не всегда удобно, то есть это не замена шаблонному/constexpr метапрограммированию, а скорее дополнение.
Re[17]: [proof-of-concept] compile time query language
EP>Изначально генерируется следующий код (условия тестовые, пока нет псевдонимов, но не суть):
EP>
EP>SELECT foo.id FROM
EP>(
EP> SELECT foo.id FROM
EP> (
EP> SELECT foo.id FROM foo WHERE foo.id>40
EP> ) WHERE foo.id>41
EP>) WHERE foo.id>42
Какой же это zero overhead? SQL выражение из строки парсится в промежуточное представление и исполняется интерпретатором. Лучше было бы сделать наоборот: SQL выражение препроцессится, из него генерится бинарное представление компилятором (исполняемый код reduce), и линкуется к программе.
Re[18]: [proof-of-concept] compile time query language
Здравствуйте, Artеm, Вы писали:
A>Какой же это zero overhead?
Zero overhead по работе с СУБД, которая есть как данность.
A>SQL выражение из строки парсится в промежуточное представление и исполняется интерпретатором.
Внутри уже готовых СУБД
A>Лучше было бы сделать наоборот: SQL выражение препроцессится, из него генерится бинарное представление компилятором (исполняемый код reduce), и линкуется к программе.
Ты мне предлагаешь СУБД написать?
Re: [proof-of-concept] compile time query language
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>В рамках одной из КСВ тем сделал proof-of-concept встроенного языка запросов времени компиляции
Дык, есть ж ODB, http://www.codesynthesis.com/products/odb/
Re[17]: [proof-of-concept] compile time query language
А ещё ведь join бывает. Тогда как? Везде надо помнить какое поле откуда взялось или какой-то врапер для join'а описывать?
Ну и это ты придумал, сильно не сразу, кстати, такой хитрый DSL, который на все эти фокусы с наследованиями ложится. А если бы была возможность как-то описывать прямо генерённые в CT структуры, то DSL генерить было бы проще.
Вот, например, хочу я написать CT компилятор regexp'ов, который при мэтчинге записывает в какие-то переменные смытчившиеся с ними диапазоны. И что мне делать?
EP>Обсуждаемый контекст относится скорее к reflection и reification. Хотя да, с метопрограммированием связан.
E>>Если уж развивать язык в эту сторону, то я бы лучше концепцию constexpr развивал. Всё равно у нас для реализации constexpr компилятор должен уметь исполнять CT с++ код без побочных эффектов, так что недалеко до того, что бы сделать так, что бы компилятор отдавал в макрос текст или АСТ или что-то вроде того, и получал наружу модифицированное тоже самое...
EP>Да, было бы хорошо, вот только этого даже на горизонте не видно. EP>И к тому же думаю метапрограммирование на уровне AST не всегда удобно, то есть это не замена шаблонному/constexpr метапрограммированию, а скорее дополнение.
Ну, это, скорее то, что надо, в отличии от нынешних Тьюринг-полных CT-решений на шаблонах...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: [proof-of-concept] compile time query language
Здравствуйте, niXman, Вы писали:
X>у меня офтопный вопрос: а зачем тут vector_noinline? в чем его надобность, и почему?
Во-первых убрать лишний заинлайненный код из сравниваемых ASM функций.
Во-вторых чтобы было видно название вызываемых функций в ASM коде (у dummy_db тоже методы NOINLINE).
И в-третьих zero overhead не гарантирует одинаковый ASM код, компилятор вполне имеет право переставлять инструкции местами и т.п. — было бы не так красноречиво. Меньший объём кода функции позволяет снизить влияние таких сторонних факторов.
Re[2]: [proof-of-concept] compile time query language
Здравствуйте, Voivoid, Вы писали:
EP>>В рамках одной из КСВ тем сделал proof-of-concept встроенного языка запросов времени компиляции V>Дык, есть ж ODB, http://www.codesynthesis.com/products/odb/
Я видел, и даже неоднократно на неё ссылался ранее.
Мой пример не является законченным решением, а лишь демонстрацией нулевых расходов, с другой стороны не думаю что в ODB нулевые расходы.
Re[18]: [proof-of-concept] compile time query language
Это мелочь, и вполне реализуемо в рамках описанного выше подхода с наследованием.
E>А ещё ведь join бывает. Тогда как? Везде надо помнить какое поле откуда взялось или какой-то врапер для join'а описывать?
Описывать придётся в любом случае, так как например будут поля с дублированными именами.
Join уже реализован в sqlpp11.
E>Ну и это ты придумал, сильно не сразу, кстати, такой хитрый DSL, который на все эти фокусы с наследованиями ложится.
Это не я придумал. Я увидел этот приём в sqlpp11, или может каком другом месте, но в sqlpp11 видел точно.
E>А если бы была возможность как-то описывать прямо генерённые в CT структуры, то DSL генерить было бы проще.
Так и тут достаточно просто. С тем что этот трюк нужно сначала придумать — да, согласен, но когда он известен само использование уже достаточно простое.
E>Вот, например, хочу я написать CT компилятор regexp'ов, который при мэтчинге записывает в какие-то переменные смытчившиеся с ними диапазоны. И что мне делать?
Например? В смысле в поля результирующей структуры? Или внешние переменные?
EP>>И к тому же думаю метапрограммирование на уровне AST не всегда удобно, то есть это не замена шаблонному/constexpr метапрограммированию, а скорее дополнение. E>Ну, это, скорее то, что надо, в отличии от нынешних Тьюринг-полных CT-решений на шаблонах...
Манипулирование AST — да, мощнее, но это низкий уровень, и далеко не самый удобный.
Вот например, текст SQL запроса в моём примере генерируется (во время компиляции) следующей функцией:
EP>Это мелочь, и вполне реализуемо в рамках описанного выше подхода с наследованием.
Ты спросил, как улучшить этот DSL, а не чего нельзя сделать на С++...
Просто проектируя DSL ты думал не о выразительности, а о том, чтобы это можно было в макрошаблонную магию затолкать...
EP>Описывать придётся в любом случае, так как например будут поля с дублированными именами. EP>Join уже реализован в sqlpp11.
Ну вот в случае 2-х namespaces, как-то удаётся обойтись без описания join...
EP>Это не я придумал.
Ну не ты, какая разница?
E>>А если бы была возможность как-то описывать прямо генерённые в CT структуры, то DSL генерить было бы проще.
EP>Так и тут достаточно просто. С тем что этот трюк нужно сначала придумать — да, согласен, но когда он известен само использование уже достаточно простое.
Оно сильно ограничивает. Например неудобно писать методы от нескольких полей...
E>>Вот, например, хочу я написать CT компилятор regexp'ов, который при мэтчинге записывает в какие-то переменные смытчившиеся с ними диапазоны. И что мне делать?
EP>Например? В смысле в поля результирующей структуры? Или внешние переменные?
И тут dataSuffixes и monthsOfYear такие же парсеры, определённые где-то выше, а может и другие, а regExpRes.dataPrefixes — результат применения dataPrefixes.
EP>Манипулирование AST — да, мощнее, но это низкий уровень, и далеко не самый удобный. EP>Вот например, текст SQL запроса в моём примере генерируется (во время компиляции) следующей функцией:
EP>IMHO, это практически самый удобный и лаконичный вариант. А вот как будет тоже самое выглядеть через манипуляцию AST?
Будет просто цикл по токенам, возможно с каким-то фильтром по типу, или по атрибутам структуры...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: [proof-of-concept] compile time query language
Круто конечно, но зачем? Вот например библиотека soci уже давно существует и позволяет встраивать sql в с++ код, но ей никто не пльзуется, ибо это никому особо не нужно. Проще вынести весь код работающий с БД в отдельный DAL слой и работать с ним.
Re[2]: [proof-of-concept] compile time query language
Здравствуйте, chaotic-kotik, Вы писали:
CK>Круто конечно, но зачем?
Это лишь пример в ответ на заявления о невозможности в другой теме.
CK>Вот например библиотека soci уже давно существует и позволяет встраивать sql в с++ код,
В SOCI нет типизации запроса, труднее проводить декомпозицию, структуры под проекции нужно писать руками, и думаю там не zero overhead.
CK>но ей никто не пльзуется, ибо это никому особо не нужно.
Я думаю это от отсутствия массового спроса на работу с СУБД из C++. Мне вот тоже такие задачи не попадаются совсем.
CK>Проще вынести весь код работающий с БД в отдельный DAL слой и работать с ним.
DAL как реализовывать? На каком языке/библиотеке?
Где делать требуемые проекции, фильтрации? Всё в DAL расписывать?
Re[2]: [proof-of-concept] compile time query language
Здравствуйте, chaotic-kotik, Вы писали:
CK>Вот например библиотека soci уже давно существует и позволяет встраивать sql в с++ код, но ей никто не пльзуется, ибо это никому особо не нужно.
я пользуюсь, и давольно давно, пока sqlpp11 не нашел.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: [proof-of-concept] compile time query language
Здравствуйте, niXman, Вы писали:
CK>>Вот например библиотека soci уже давно существует и позволяет встраивать sql в с++ код, но ей никто не пльзуется, ибо это никому особо не нужно. X>я пользуюсь, и давольно давно, пока sqlpp11 не нашел.
А какого типа у тебя задачи? Хотя бы из какой области? С какими СУБД работаешь?
Re[4]: [proof-of-concept] compile time query language
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>А какого типа у тебя задачи? Хотя бы из какой области?
та что-то взять из БД, положить, етц... ничего критичного к производительности нет.
EP>С какими СУБД работаешь?
sqlite, mysql, postgresql.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[5]: [proof-of-concept] compile time query language
Здравствуйте, niXman, Вы писали:
EP>>А какого типа у тебя задачи? Хотя бы из какой области? X>та что-то взять из БД, положить, етц... ничего критичного к производительности нет.
А области какие? Сервисы или например пользовательские приложения?
Re[6]: [proof-of-concept] compile time query language
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>А области какие? Сервисы или например пользовательские приложения?
все же больше сервисов... есть игровой проект, весьма популярный, там постгрес в качестве хранилища истории действий. там порядка 2к записей в секунду. и это отдельный сервер.
остальные совсем не нагруженные.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[20]: [proof-of-concept] compile time query language
Здравствуйте, Erop, Вы писали:
EP>>Это мелочь, и вполне реализуемо в рамках описанного выше подхода с наследованием. E>Ты спросил, как улучшить этот DSL, а не чего нельзя сделать на С++... E>Просто проектируя DSL ты думал не о выразительности, а о том, чтобы это можно было в макрошаблонную магию затолкать...
Я думал о том чтобы сделать пример при малых усилиях.
Если же говорить о выразительности, то интересно сделать автоматический join основанный на связях между таблицами в БД — в большинстве случаев именно это и происходит. То есть выражение вида select(foo.name, bar.value) автоматически породит from с необходимыми join'ами, выведенными на основе графа связей. И вот в таком варианте имена таблиц в select'е более чем оправданны.
EP>>Описывать придётся в любом случае, так как например будут поля с дублированными именами. EP>>Join уже реализован в sqlpp11. E>Ну вот в случае 2-х namespaces, как-то удаётся обойтись без описания join...
Каких namespaces?
E>Например неудобно писать методы от нескольких полей...
Что имеется в виду?
E>>>Вот, например, хочу я написать CT компилятор regexp'ов, который при мэтчинге записывает в какие-то переменные смытчившиеся с ними диапазоны. И что мне делать? EP>>Например? В смысле в поля результирующей структуры? Или внешние переменные? E>В смысле пишу что-то вроде
И тут dataSuffixes и monthsOfYear такие же парсеры, определённые где-то выше, а может и другие, а regExpRes.dataPrefixes — результат применения dataPrefixes.
В рамках текущего стандарта придётся писать вот так:
auto regExp = REGEXP(R"((@dataPrefixes){data:{day:\d?\d}\\{month:(\d?\d)|(@monthsOfYear)}\\{year:(\d\d)?\d\d)}(@dataSuffixes))", dataPrefixes, monthsOfYear, dataSuffixes);
Тогда твой код regExpRes.dataPrefixes.Type заработает. По аналогии с этим примером
Чтобы не было выделенного, и без макросов, понадобятся две фичи:
1) описанный выше std::reification
2) захват контекста — примерно так как делает лямбда
EP>>Манипулирование AST — да, мощнее, но это низкий уровень, и далеко не самый удобный. EP>>Вот например, текст SQL запроса в моём примере генерируется (во время компиляции) следующей функцией: EP>>IMHO, это практически самый удобный и лаконичный вариант. А вот как будет тоже самое выглядеть через манипуляцию AST? E>Будет просто цикл по токенам, возможно с каким-то фильтром по типу, или по атрибутам структуры...
Это будет как минимум не проще, и при этом на более низком уровне.
Re[3]: [proof-of-concept] compile time query language
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Это лишь пример в ответ на заявления о невозможности в другой теме.
Тогда вопросов больше нет, действительно неплохая демонстрация возможностей языка
EP>Я думаю это от отсутствия массового спроса на работу с СУБД из C++. Мне вот тоже такие задачи не попадаются совсем.
Скорее tradeoffs при работе с БД немного другие и производительность достигается другими методами.
CK>>Проще вынести весь код работающий с БД в отдельный DAL слой и работать с ним.
EP>DAL как реализовывать? На каком языке/библиотеке?
Я как правило предпочитаю нативную клиентскую библиотеку использовать ну и обычные текстовые запросы + prepare для некоторых.
EP>Где делать требуемые проекции, фильтрации? Всё в DAL расписывать?
Да, а что такого? Вынести в отдельный модуль, чтобы все приложение работало через какой-нибудь абстрактный интерфейс и не знало вообще, с чем оно работает, с БД, или еще каким-нибудь источником данных. Тут можно свапнуть БД на другую (например в тестах использовать sqlite вместо постгреса или вообще какой-нибудь nosql). Я еще в одном проекте видел такое — каждый row в результатах запроса конвертировался в boost.property_tree, который передавался кругом. Все ф-ии работающие с данными принимали property_tree, все довольно универсально и гибко было, скажем коду было не важно, пришел property_tree из базы или из POST запроса. Накладные расходы конечно большие, но это сильно лучше чем размазывать работу с БД по всему приложению и при каждом изменении схемы переписывать код и пересобирать.
И что ты понимаешь под фильтрациями? Where statement в SQL или обработку результатов запроса?
Здравствуйте, niXman, Вы писали:
X>все же больше сервисов... есть игровой проект, весьма популярный, там постгрес в качестве хранилища истории действий. там порядка 2к записей в секунду. и это отдельный сервер. X>остальные совсем не нагруженные.