Re[16]: [proof-of-concept] compile time query language
От: Evgeny.Panasyuk Россия  
Дата: 12.07.16 08:43
Оценка:
Здравствуйте, Erop, Вы писали:

E>>>Что бы описать структуру с несколькими полями, предлагается выводиться из всех таких структур? Или какая идея?

EP>>Наследование от всех таких структур
EP>>
EP>>template<typename ...Columns>
EP>>struct row : Columns::field...
EP>>{};
EP>>

E>Думаешь это удобно?

С какой стороны? Пользователя или реализации?

Со стороны пользователя вполне удобно, используется например в 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 string
    bool 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
От: Artеm Австралия жж
Дата: 12.07.16 08:56
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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
От: Evgeny.Panasyuk Россия  
Дата: 12.07.16 09:00
Оценка:
Здравствуйте, Artеm, Вы писали:

A>Какой же это zero overhead?


Zero overhead по работе с СУБД, которая есть как данность.

A>SQL выражение из строки парсится в промежуточное представление и исполняется интерпретатором.


Внутри уже готовых СУБД

A>Лучше было бы сделать наоборот: SQL выражение препроцессится, из него генерится бинарное представление компилятором (исполняемый код reduce), и линкуется к программе.


Ты мне предлагаешь СУБД написать?
Re: [proof-of-concept] compile time query language
От: niXman Ниоткуда https://github.com/niXman
Дата: 12.07.16 11:58
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

у меня офтопный вопрос: а зачем тут vector_noinline? в чем его надобность, и почему?

спасибо.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: [proof-of-concept] compile time query language
От: Voivoid Россия  
Дата: 12.07.16 12:04
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>В рамках одной из КСВ тем сделал proof-of-concept встроенного языка запросов времени компиляции

Дык, есть ж ODB, http://www.codesynthesis.com/products/odb/
Re[17]: [proof-of-concept] compile time query language
От: Erop Россия  
Дата: 12.07.16 12:08
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>С какой стороны? Пользователя или реализации?

Со всех.

EP>
EP>for (const auto& row : db(select(foo.name, foo.hasFun).from(foo).where(foo.id > 17 and foo.name.like("%bar%"))))
EP>
Ты можешь придумать более удобный синтаксис?

Конечно могу.
можно сделать foo. факультативным...
Так удобнее же:
EP>for (const auto& row : db(select(name, hasFun).from(foo).where(id > 17 and name.like


А ещё ведь 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
От: Evgeny.Panasyuk Россия  
Дата: 12.07.16 14:09
Оценка: +1
Здравствуйте, niXman, Вы писали:

X>у меня офтопный вопрос: а зачем тут vector_noinline? в чем его надобность, и почему?


Во-первых убрать лишний заинлайненный код из сравниваемых ASM функций.
Во-вторых чтобы было видно название вызываемых функций в ASM коде (у dummy_db тоже методы NOINLINE).
И в-третьих zero overhead не гарантирует одинаковый ASM код, компилятор вполне имеет право переставлять инструкции местами и т.п. — было бы не так красноречиво. Меньший объём кода функции позволяет снизить влияние таких сторонних факторов.
Re[2]: [proof-of-concept] compile time query language
От: Evgeny.Panasyuk Россия  
Дата: 12.07.16 14:12
Оценка:
Здравствуйте, Voivoid, Вы писали:

EP>>В рамках одной из КСВ тем сделал proof-of-concept встроенного языка запросов времени компиляции

V>Дык, есть ж ODB, http://www.codesynthesis.com/products/odb/

Я видел, и даже неоднократно на неё ссылался ранее.
Мой пример не является законченным решением, а лишь демонстрацией нулевых расходов, с другой стороны не думаю что в ODB нулевые расходы.
Re[18]: [proof-of-concept] compile time query language
От: Evgeny.Panasyuk Россия  
Дата: 12.07.16 15:20
Оценка:
Здравствуйте, Erop, Вы писали:

EP>>
EP>>for (const auto& row : db(select(foo.name, foo.hasFun).from(foo).where(foo.id > 17 and foo.name.like("%bar%"))))
EP>>
Ты можешь придумать более удобный синтаксис?

E>Конечно могу.
E>можно сделать foo. факультативным...
E>Так удобнее же:
EP>for (const auto& row : db(select(name, hasFun).from(foo).where(id > 17 and name.like


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

E>А ещё ведь join бывает. Тогда как? Везде надо помнить какое поле откуда взялось или какой-то врапер для join'а описывать?


Описывать придётся в любом случае, так как например будут поля с дублированными именами.
Join уже реализован в sqlpp11.

E>Ну и это ты придумал, сильно не сразу, кстати, такой хитрый DSL, который на все эти фокусы с наследованиями ложится.


Это не я придумал. Я увидел этот приём в sqlpp11, или может каком другом месте, но в sqlpp11 видел точно.

E>А если бы была возможность как-то описывать прямо генерённые в CT структуры, то DSL генерить было бы проще.


Так и тут достаточно просто. С тем что этот трюк нужно сначала придумать — да, согласен, но когда он известен само использование уже достаточно простое.

E>Вот, например, хочу я написать CT компилятор regexp'ов, который при мэтчинге записывает в какие-то переменные смытчившиеся с ними диапазоны. И что мне делать?


Например? В смысле в поля результирующей структуры? Или внешние переменные?

EP>>И к тому же думаю метапрограммирование на уровне AST не всегда удобно, то есть это не замена шаблонному/constexpr метапрограммированию, а скорее дополнение.

E>Ну, это, скорее то, что надо, в отличии от нынешних Тьюринг-полных CT-решений на шаблонах...

Манипулирование AST — да, мощнее, но это низкий уровень, и далеко не самый удобный.
Вот например, текст SQL запроса в моём примере генерируется (во время компиляции) следующей функцией:
template<typename Source, typename Condition, typename ...Columns>
constexpr auto make_sql
(
    Source source,
    Condition condition,
    Columns... columns
)
{
    return concat
    (
        CTQL_STRING("SELECT "), concat_columns(columns...),
        CTQL_STRING(" FROM "), source_string(source),
        skip_if_empty(condition, concat(CTQL_STRING(" WHERE "), condition))
    );
}

В более новых стандартах, можно будет писать вот так:
constexpr auto make_sql(auto source, auto condition, auto... columns)
{
    return concat
    (
        "SELECT "_S, concat_columns(columns...),
        " FROM "_S, source_string(source),
        skip_if_empty(condition, concat(" WHERE "_S, condition))
    );
}

IMHO, это практически самый удобный и лаконичный вариант. А вот как будет тоже самое выглядеть через манипуляцию AST?
Re[19]: [proof-of-concept] compile time query language
От: Erop Россия  
Дата: 12.07.16 15:44
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:


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

Ты спросил, как улучшить этот DSL, а не чего нельзя сделать на С++...
Просто проектируя DSL ты думал не о выразительности, а о том, чтобы это можно было в макрошаблонную магию затолкать...

EP>Описывать придётся в любом случае, так как например будут поля с дублированными именами.

EP>Join уже реализован в sqlpp11.
Ну вот в случае 2-х namespaces, как-то удаётся обойтись без описания join...

EP>Это не я придумал.

Ну не ты, какая разница?

E>>А если бы была возможность как-то описывать прямо генерённые в CT структуры, то DSL генерить было бы проще.


EP>Так и тут достаточно просто. С тем что этот трюк нужно сначала придумать — да, согласен, но когда он известен само использование уже достаточно простое.

Оно сильно ограничивает. Например неудобно писать методы от нескольких полей...

E>>Вот, например, хочу я написать CT компилятор regexp'ов, который при мэтчинге записывает в какие-то переменные смытчившиеся с ними диапазоны. И что мне делать?


EP>Например? В смысле в поля результирующей структуры? Или внешние переменные?


В смысле пишу что-то вроде
auto regExp = RegExp( (@dataPrefixes){data:{day:\d?\d}\\{month:(\d?\d)|(@monthsOfYear)}\\{year:(\d\d)?\d\d)}(@dataSuffixes) );
auto regExpRes = regExp << line;
if( regExpRes ) {
    dayta = MyData( regExpRes.day, regExpRes.month, regExpRes.year );
    dataType = regExpRes.dataPrefixes.Type;
}
И тут dataSuffixes и monthsOfYear такие же парсеры, определённые где-то выше, а может и другие, а regExpRes.dataPrefixes — результат применения dataPrefixes.


EP>Манипулирование AST — да, мощнее, но это низкий уровень, и далеко не самый удобный.

EP>Вот например, текст SQL запроса в моём примере генерируется (во время компиляции) следующей функцией:


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


Будет просто цикл по токенам, возможно с каким-то фильтром по типу, или по атрибутам структуры...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: [proof-of-concept] compile time query language
От: chaotic-kotik  
Дата: 12.07.16 16:10
Оценка:
Круто конечно, но зачем? Вот например библиотека soci уже давно существует и позволяет встраивать sql в с++ код, но ей никто не пльзуется, ибо это никому особо не нужно. Проще вынести весь код работающий с БД в отдельный DAL слой и работать с ним.
Re[2]: [proof-of-concept] compile time query language
От: Evgeny.Panasyuk Россия  
Дата: 12.07.16 16:19
Оценка:
Здравствуйте, chaotic-kotik, Вы писали:

CK>Круто конечно, но зачем?


Это лишь пример в ответ на заявления о невозможности в другой теме.

CK>Вот например библиотека soci уже давно существует и позволяет встраивать sql в с++ код,


В SOCI нет типизации запроса, труднее проводить декомпозицию, структуры под проекции нужно писать руками, и думаю там не zero overhead.

CK>но ей никто не пльзуется, ибо это никому особо не нужно.


Я думаю это от отсутствия массового спроса на работу с СУБД из C++. Мне вот тоже такие задачи не попадаются совсем.

CK>Проще вынести весь код работающий с БД в отдельный DAL слой и работать с ним.


DAL как реализовывать? На каком языке/библиотеке?
Где делать требуемые проекции, фильтрации? Всё в DAL расписывать?
Re[2]: [proof-of-concept] compile time query language
От: niXman Ниоткуда https://github.com/niXman
Дата: 12.07.16 16:32
Оценка: 10 (1)
Здравствуйте, chaotic-kotik, Вы писали:

CK>Вот например библиотека soci уже давно существует и позволяет встраивать sql в с++ код, но ей никто не пльзуется, ибо это никому особо не нужно.

я пользуюсь, и давольно давно, пока sqlpp11 не нашел.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: [proof-of-concept] compile time query language
От: Evgeny.Panasyuk Россия  
Дата: 12.07.16 16:46
Оценка:
Здравствуйте, niXman, Вы писали:

CK>>Вот например библиотека soci уже давно существует и позволяет встраивать sql в с++ код, но ей никто не пльзуется, ибо это никому особо не нужно.

X>я пользуюсь, и давольно давно, пока sqlpp11 не нашел.

А какого типа у тебя задачи? Хотя бы из какой области? С какими СУБД работаешь?
Re[4]: [proof-of-concept] compile time query language
От: niXman Ниоткуда https://github.com/niXman
Дата: 12.07.16 16:57
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>А какого типа у тебя задачи? Хотя бы из какой области?

та что-то взять из БД, положить, етц... ничего критичного к производительности нет.

EP>С какими СУБД работаешь?

sqlite, mysql, postgresql.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[5]: [proof-of-concept] compile time query language
От: Evgeny.Panasyuk Россия  
Дата: 12.07.16 17:00
Оценка:
Здравствуйте, niXman, Вы писали:

EP>>А какого типа у тебя задачи? Хотя бы из какой области?

X>та что-то взять из БД, положить, етц... ничего критичного к производительности нет.

А области какие? Сервисы или например пользовательские приложения?
Re[6]: [proof-of-concept] compile time query language
От: niXman Ниоткуда https://github.com/niXman
Дата: 12.07.16 17:08
Оценка: 16 (2)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>А области какие? Сервисы или например пользовательские приложения?

все же больше сервисов... есть игровой проект, весьма популярный, там постгрес в качестве хранилища истории действий. там порядка 2к записей в секунду. и это отдельный сервер.
остальные совсем не нагруженные.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[20]: [proof-of-concept] compile time query language
От: Evgeny.Panasyuk Россия  
Дата: 12.07.16 22:19
Оценка:
Здравствуйте, 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>В смысле пишу что-то вроде
auto regExp = RegExp( (@dataPrefixes){data:{day:\d?\d}\\{month:(\d?\d)|(@monthsOfYear)}\\{year:(\d\d)?\d\d)}(@dataSuffixes) );
E>auto regExpRes = regExp << line;
E>if( regExpRes ) {
E>    dayta = MyData( regExpRes.day, regExpRes.month, regExpRes.year );
E>    dataType = regExpRes.dataPrefixes.Type;
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 заработает. По аналогии с этим примером
Автор: Evgeny.Panasyuk
Дата: 12.10.14
.

Чтобы не было выделенного, и без макросов, понадобятся две фичи:
1) описанный выше std::reification
2) захват контекста — примерно так как делает лямбда

EP>>Манипулирование AST — да, мощнее, но это низкий уровень, и далеко не самый удобный.

EP>>Вот например, текст SQL запроса в моём примере генерируется (во время компиляции) следующей функцией:
EP>>IMHO, это практически самый удобный и лаконичный вариант. А вот как будет тоже самое выглядеть через манипуляцию AST?
E>Будет просто цикл по токенам, возможно с каким-то фильтром по типу, или по атрибутам структуры...

Это будет как минимум не проще, и при этом на более низком уровне.
Re[3]: [proof-of-concept] compile time query language
От: chaotic-kotik  
Дата: 13.07.16 09:29
Оценка:
Здравствуйте, 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 или обработку результатов запроса?
Отредактировано 13.07.2016 9:34 chaotic-kotik . Предыдущая версия .
Re[7]: [proof-of-concept] compile time query language
От: chaotic-kotik  
Дата: 13.07.16 09:35
Оценка:
Здравствуйте, niXman, Вы писали:

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

X>остальные совсем не нагруженные.

2к это тоже совсем не нагруженный
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.