Здравствуйте, Ночной Смотрящий, Вы писали:
НС>>>Практические соображения и алгоритмическая выразительность это разные вещи. Алгоритмически все это можно было бы уложить в один небольшой метод. EP>>Номинально да, на практике же имеем совсем не номинальный boilerplate. НС>На практике такие задачи встречаются крайне редко.
У меня постоянно.
Тем не менее, разговор-то не про часто/нечасто.
НС>>>Далеко не только. Еще недавно она была нужна даже для таких базовых вещей как лямбды. EP>>"Недавно" это уже лет шесть как назад. НС>Меньше 5.
Они появились раньше релиза стандарта 2011 — в MSVS 2010 и GCC 4.5 (2010).
Кстати, какого года там в C# стандарт ISO/ECMA?
НС>>>И для плохонького аналога анонимных типов она понадобилась. Причем ее не хватило в итоге, и пришлось допиливать при помощи макросов препроцессора. EP>>Каких конкретно макросов? НС>http://rsdn.ru/forum/dotnet/6462036.1
Это же можно заменить на внешнюю кодогенерацию, так как всё равно придётся как-то синхронизироваться со схемой данных. В Linq2DB также предлагается внешняя кодогенерация.
НС>>>Ты обсуждаешь простейший алгоритм на С++ с его конкретной реализацией для дотнета, содержащей кучу подробностей, связанных со спецификой платформы. Это самая натуральная демагогия. EP>>На C++ из всей "специфики платформы" к этому алгоритму будет несколько десятков строк врапперов для Range интерфейсов НС>И?
И то что в полной реализации C++ будет намного меньше чем то что есть в CodeJam. Это пример к исходному тезису.
НС>Понимаешь, никто тут не утверждает, в отличие от любителей С++, что С# круче всех и лишен каких либо недостатков.
А я разве утверждал что C++ круче всех? Я говорил про конкретный аспект, в котором он действительно лучше, но из этого не следует что "C++ круче всех"
НС>В общем, совершенно стандартная ситуация — где то выигрываем, где то проигрываем. И только любители С++ чудесным образом не замечают кучу недостатков любимого языка, и разводят на тему "С++ круче всех" километровые флеймы.
К чему это? Я вполне замечаю недостатки и сразу признаю, и поэтому флеймов из этого не вырастает. Более того, без проблем использую C# когда требуется, и если нужна будет ещё и работа с БД — посмотрю на linq2db, и ЕМНИП я даже успел сказать это в текущем топике.
Километровый флейм тут (да и соседней теме) вырос от нежелания признать что простейший алгоритм вылился в несколько сот строк boilerplate, причём плохо поддерживаемых, ибо много копипасты + текстовая кодогенерация.
Аргументация же оппонентов постоянно витает где-то в далеких от исходного тезиса темах, типа экономической целесообразности, наличия мух в голове авторов кода, редкости таких ситуаций, метапрограммирования на макросах и шаблонах и т.п.
Re[180]: Тормознутость и кривость linq. Compile-time EDSL DB
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>>>>>А это для лучшего перформанса. EP>>>>Так я и говорю, этот код пришлось написать из вполне конкретных практических соображений. Был бы язык/платформа/компилятор мощнее — его бы и не пришлось писать, о чем собственно и речь. S>>>А то, что тебе приходится писать жуткие макросо-шаблоны в которых разбираешься только ты считаешь достоинством платформы? EP>>Так это же для реализации языка запросов времени компиляции с нулевыми накладными расходами — в рамках непосредственно C# такое и вовсе нереализуемо НС>А оно не особо то и нужно.
Так это же был ответ на выделенное. К обсуждению алгоритма min element он зачем-то притянул метапрограммирование в совершенно другом примере, который к тому же и не реализуем на C#.
НС>А оно не особо то и нужно. Компиляции при первом использовании вполне достаточно в 99.99% случаев.
Так я и не спорю, возможно и не стоит. Уже выше писал:
EP>>>Такие запросы тоже можно сгенерировать во время компиляции — вопрос в количестве вариантов.
IT>>В этом нет смысла. Единственная проблема ET — это сложность получения хешь функции самого дерева, т.к. оно перестраивается компилятором при каждом вызове. Если делать свой собственный DSL, то такую возможность можно предусмотреть и тогда проблема кеширования запросов отпадает. Т.е. не стоит выпрыгивать из штанов в compile-time, получая неполноценный результат.
EP>Не спорю, возможно и не стоит.
EP>Я лишь говорю о том, что многие преимущества linq, в том числе и то что ты называешь главным козырем — type-safety, можно получить через генерацию compile-time, даже для динамических запросов. Насколько же это целесообразно — отдельный и важный вопрос.
Re[182]: Тормознутость и кривость linq. Compile-time EDSL DB
Здравствуйте, Serginio1, Вы писали:
S>>>>> А то, что тебе приходится писать жуткие макросо-шаблоны в которых разбираешься только ты считаешь достоинством платформы? EP>>>>Так это же для реализации языка запросов времени компиляции с нулевыми накладными расходами — в рамках непосредственно C# такое и вовсе нереализуемо S>>> Да можно, только это никому не нужно. Разберись в предметной области. S>>>... EP>> S> Молодец, то что ниже опускаешь. И игнорируешь.
Каков хитрец, отредактировал сообщение и теперь говоришь что я игнорирую добавленную часть
S>
S> Но вполне возможно, что будет жесткая привязка к провайдеру в EF7 .Net Native.
S> Если можно динамически скомпилировать, то что мешает это сделать при компиляцмм программмы?
S> То есть твое утверждение, что " в рамках непосредственно C# такое и вовсе нереализуемо " S>Это ложь. Это не реализуемо в рамках конкретной реализации EF. Но никак не языка.
Так я же говорю про "непосредственно C#", а не какие-либо внешние утилиты.
Re[181]: Тормознутость и кривость linq. Compile-time EDSL DB
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Километровый флейм тут (да и соседней теме) вырос от нежелания признать что простейший алгоритм вылился в несколько сот строк boilerplate, причём плохо поддерживаемых, ибо много копипасты + текстовая кодогенерация. EP>Аргументация же оппонентов постоянно витает где-то в далеких от исходного тезиса темах, типа экономической целесообразности, наличия мух в голове авторов кода, редкости таких ситуаций, метапрограммирования на макросах и шаблонах и т.п.
Еще раз. Тебе я привел кучу примеров. Приведу еще один
//if (value == null)
// source=source.Where(x=>x!=null); // Уберем фильтр на Linq из-за тормоза делегатаbool isFirst=true;
bool fl=0;
foreach(var item in source)
{
// Поставим фильтр сюдаif (isNullable && item == null) continue;
var x = selector(item );
if (isFirst)
{
isFirst=false;
fl=-1;
}
else
fl=comparer.Compare(x,value);
if (fl< 0)
{
value = x;
result= item;
}
}
if (isFirst)
{
// по их алгоритму при пустом списке вызвать исключение для Nullableif (isNullable)
throw NoElementsException();
else
return default(TSource); // вернуть default при пустом списке
}
return result;
Получим тот же перфоманс без копи-пасте.
Приводи свой алгоритм на C++ который в 100 раз меньше.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>У меня постоянно.
Значит .NET тебе плохо подходит.
EP>Так в языке запросов это не используется
При чем тут язык запросов?
EP>, там не нужны анонимные типы. Все макросы что там есть используются исключительно для определения таблиц:
Суть ad-hoc типов в том и состоит, что сам запрос операцией проекции порождает новую "таблицу". Я ж ведь не зря говорил про простейший случай. Как вместо простой ссылки на поле таблицы нарисовалось выражение — уже какой то NEW вылез. А если после операции проекции нам надо опять фильтр наложить? Сгруппировать? Еще одну проекцию добавить? Сделать union двух разных по происхождению но с совпадающим типом проекций?
EP>
Это же можно заменить на внешнюю кодогенерацию, так как всё равно придётся как-то синхронизироваться со схемой данных.
А руками если написать, во что это превратится?
EP>И то что в полной реализации C++ будет намного меньше чем то что есть в CodeJam.
Если это будет С++ для safe дотнета, то не особо меньше. А сравнивать алгоритмы с разными нефункциональными требованиями, причем сравнивать именно эти самые нефункциональные требования — чистейшая демагогия.
НС>>Понимаешь, никто тут не утверждает, в отличие от любителей С++, что С# круче всех и лишен каких либо недостатков. EP>А я разве утверждал что C++ круче всех?
А разве ты тут писал про то, что С++ в чем то хуже С#? Хотя бы пару раз?
EP> Я говорил про конкретный аспект, в котором он действительно лучше
Да нет. Конкретный аспект называется дженерик-арифметика, а ты обобщил на всю алгоритмическую выразительность. Если бы ты сказал, что дженерик арифметику на С++ писать намного проще — тебе бы и слова никто не сказал.
EP>К чему это? Я вполне замечаю недостатки и сразу признаю
Ссылочки можно?
EP>Аргументация же оппонентов постоянно витает где-то в далеких от исходного тезиса темах, типа экономической целесообразности, наличия мух в голове авторов кода, редкости таких ситуаций, метапрограммирования на макросах и шаблонах и т.п.
А на самом деле все с точностью до наоборот. Оппоненты говорят о вполне конкретных моментах в реальном коде и конкретном опыте работы, а ты в ответ пичкаешь их полутеоретическими изысканиями в вопросах, в которых опыта у тебя около нуля. Та еще ржака смотреть, как ты с алексом рассказываете про то как надо правильно работать с БД Синклеру и ИТ.
Re[181]: Тормознутость и кривость linq. Compile-time EDSL DB
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>Не спорю, возможно и не стоит. EP>>Я лишь говорю о том, что многие преимущества linq, в том числе и то что ты называешь главным козырем — type-safety, можно получить через генерацию compile-time
Так нельзя же! Потому что запросы динамические часто (или даже почти всегда, я и ИТ примеры таких ситуаций приводили), статически их нельзя создать в принципе. При этом вся type safety в линке сохраняется в полный рост, включая, при необходимости, даже проверки в рантайме, а вот ваши стрококлеи остаются при этом не у дел, в лучшем случае обработав совсем примитивные варианты с риском получить комбинаторный взрыв.
Понимаешь, твоих оппонентов не интересует возможность теоретически получить какой то результат в некоторых ситуациях. Им интересен реальный рабочий инструмент. И linq2db таковым является в полный рост, а вот sqlpp — увы и ах.
Re[183]: Тормознутость и кривость linq. Compile-time EDSL DB
S>> То есть твое утверждение, что " в рамках непосредственно C# такое и вовсе нереализуемо " S>>Это ложь. Это не реализуемо в рамках конкретной реализации EF. Но никак не языка.
EP>Так я же говорю про "непосредственно C#", а не какие-либо внешние утилиты.
То есть например если это будет сделано в компиляторе .Net Native это внешняя утилита?
Она кстати использует Компилятор С++ https://rsdn.ru/forum/flame.comp/6497386.1
.NET Native использует то же сервер, что и компилятор C++, который оптимизирован для статических сценариев предварительной компиляции.
Проблема динамического компилятора в том, что он не оптимизирует код.
При работе с провайдером ему подается ET которое он может скомпилировать и закэшировать.
То, что можно в динамике, можно сделать и в статике со статическим ET.
С заранее известному провайдеру можно пойти двумя способами.
1. Трансформация IL кода. Разобрав существующий IL код и встретив IQueryable, можно получить статическое ET скормить его провайдеру и получить IL код и заменить его.
2. Например можно создать для .Net Native расширения которые будут сразу компилировать.
Здесь проблема не в языке, а в компиляторе.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Ночной Смотрящий, Вы писали: EP>>У меня постоянно. НС>Значит .NET тебе плохо подходит.
Не подходит к моим текущим задачам. EP>>Так в языке запросов это не используется НС>При чем тут язык запросов?
При том что в моём примере на генерацию запроса и т.п. во время компиляции этого макроса нет. EP>>, там не нужны анонимные типы. Все макросы что там есть используются исключительно для определения таблиц: НС>Суть ad-hoc типов в том и состоит,
Я не знаю что ты называешь ad-hoc типами. Я даже отдельную тему с вопросом создал.
Либо конкретно C# Anonymous Type, либо синтезирование нового типа по месту (ad-hoc) что не означает только Anonymous Type.
Пример с макросом NEW был именно на Anonymous Type, и в другой теме. Синтезирование же типов по месту реализуется в том числе и другими механизмами. НС>что сам запрос операцией проекции порождает новую "таблицу". Я ж ведь не зря говорил про простейший случай. Как вместо простой ссылки на поле таблицы нарисовалось выражение — уже какой то NEW вылез.
Нет в моём примере никакого макроса NEW, он был в другой теме. Вот пример использования:
Тут второй select добавляет колонку в проекцию, это конечно не совсем верно, но для демонстрации изменения проекции вполне подойдёт. НС>Сделать union двух разных по происхождению но с совпадающим типом проекций?
Не вижу проблемы, особенно если типы совпадают. EP>>
Это же можно заменить на внешнюю кодогенерацию, так как всё равно придётся как-то синхронизироваться со схемой данных. НС>А руками если написать, во что это превратится?
Вот отформатированный вывод препроцессора:
Скрытый текст
struct foo_aux
{
using table_type = foo_aux;
struct id_column
{
struct field_id
{
struct name_string
{
static constexpr auto value() { return"id"; }
};
template <typename T>
struct field
{
T id;
};
template <typename T>
static auto &access(T &x)
{
return x.id;
}
};
using type = CTQL::table_column<table_type, int, field_id>;
};
struct code_column
{
struct field_code
{
struct name_string
{
static constexpr auto value() { return"code"; }
};
template <typename T>
struct field
{
T code;
};
template <typename T>
static auto &access(T &x)
{
return x.code;
}
};
using type = CTQL::table_column<table_type, int, field_code>;
};
struct value_column
{
struct field_value
{
struct name_string
{
static constexpr auto value() { return"value"; }
};
template <typename T>
struct field
{
T value;
};
template <typename T>
static auto &access(T &x)
{
return x.value;
}
};
using type = CTQL::table_column<table_type, double, field_value>;
};
struct number_column
{
struct field_number
{
struct name_string
{
static constexpr auto value() { return"number"; }
};
template <typename T>
struct field
{
T number;
};
template <typename T>
static auto &access(T &x)
{
return x.number;
}
};
using type = CTQL::table_column<table_type, int, field_number>;
};
struct name_string
{
static constexpr auto value() { return"foo"; }
};
using type = CTQL::make_table<name_string, id_column, code_column, value_column, number_column>;
};
foo_aux::type foo;
EP>>И то что в полной реализации C++ будет намного меньше чем то что есть в CodeJam. НС>Если это будет С++ для safe дотнета, то не особо меньше. А сравнивать алгоритмы с разными нефункциональными требованиями, причем сравнивать именно эти самые нефункциональные требования — чистейшая демагогия.
Есть задача написать алгоритм, естественно нормальным способом, а не номинальным или абы-каким. И вот в CodeJam руководствуясь вполне практическими целями и написали.
А рассуждения о нефункциональности требований и т.п. это всё лирика. Есть реальный код, и его много. НС>>>Понимаешь, никто тут не утверждает, в отличие от любителей С++, что С# круче всех и лишен каких либо недостатков. EP>>А я разве утверждал что C++ круче всех? НС>А разве ты тут писал про то, что С++ в чем то хуже С#? Хотя бы пару раз?
Из текущего топика:
EP>>>>>Лямбды лаконичнее — да, реализация алгоритма — нет.
S>>>> Если ты про замыкания, то там строится класс компилятором.
EP>>>Я про синтаксис использования лямбд.
S>> По мне так все сообразно функциональным языкам. Автоматический вывод типа.
EP>И? Ты вообще не понимаешь о чём идёт речь? Я говорю что синтаксис лямбд лаконичней в C# — нет лишних скобок, return и auto.
EP>> Я говорил про конкретный аспект, в котором он действительно лучше НС>Да нет. Конкретный аспект называется дженерик-арифметика, а ты обобщил на всю алгоритмическую выразительность. Если бы ты сказал, что дженерик арифметику на С++ писать намного проще — тебе бы и слова никто не сказал.
Что такое "дженерик-арифметика", конкретно? EP>>К чему это? Я вполне замечаю недостатки и сразу признаю НС>Ссылочки можно?
Выше было про лямбды. Сейчас искать лень, если ещё найду — то скину. НС>Та еще ржака смотреть, как ты с алексом рассказываете про то как надо правильно работать с БД Синклеру и ИТ.
А где я вообще сказал что я показываю как надо правильно работать с БД?
Я утверждаю что язык запросов времени компиляции с минимальным или нулевым overhead'ом вполне реализуем (причём необязательно на C++, это может быть и например D/Rust/Nemerle). ВСЁ — это мой главный тезис во всей этой ветке.
Кто-то выше утверждает что это невозможно — я в ответ привожу конкретные примеры.
При этом не давал оценки реальной практической необходимости именно такого варианта.
Re[182]: Тормознутость и кривость linq. Compile-time EDSL DB
Здравствуйте, Ночной Смотрящий, Вы писали:
EP>>>Не спорю, возможно и не стоит. EP>>>Я лишь говорю о том, что многие преимущества linq, в том числе и то что ты называешь главным козырем — type-safety, можно получить через генерацию compile-time НС>Так нельзя же!
Для статических и некоторых динамических — можно. Для остальных есть шанс получить меньший overhead.
НС>Потому что запросы динамические часто
Нет, это у тебя проблемы со знанием предметной области. По моему опыту, в типичном ERP приложении примерно 90% запросов не содержат динамических ветвлений. Так что 1000 запросов это вообще ни о чем.
_>>Приложение с 1000 разных статических запросов к СУБД? ) Это было бы любопытно взглянуть на подобного эпичного монстра... )))
НС>1000 запросов это эпичный монстр?
?
НС>Понимаешь, твоих оппонентов не интересует возможность теоретически получить какой то результат в некоторых ситуациях.
За всех не говори.
Например они делают заявления о теоретической возможности/невозможности чего-то, с этим я и спорю. Например:
G>>Это api для более-менее типизированного построения примитивных запросов. Он не может никаким образом получить два разных запроса из одного и того же куска кода. Даже теоретически.
EP>Это ещё почему? Например у него есть коннектор в БД, и к обычным контейнерам — один и тот же запрос может выполнять совершенно разные веши
EP>>>>Тип в который в том числе закодировано дерево выражения. На C++ это реализуется с помощью техники Expression Templates, которой уже более двадцати лет.
G>>>Показывай минимально работающий пример, который обходит дерево и строит SQL.
EP>>Показывающий что конкретно? Проекции? Фильтры? Автоматические join'ы по связям?
G>Фильтры и проекции, с джоинами потом разберемся
EP>>Это всё ни одна сотня строк кода, реализовать которые мне не интересно.
G>Тогда какой смысл в том, что ты пишешь? На практике никто такое не сделал, значит невозможно. Иначе уже была бы реализован аналог linq на C++.
Или например спрашивают про реализацию:
G>1) Так ты покажи макрос conditional или что там у тебя. А то так можно любой код написать и объявить его "статическим".
G>2) Как делать декомпозицию \ композицию таких запросов? В идеале так:http://blog.gandjustas.ru/2010/05/30/iqueryable-generics/
EP>>Так и в случае с compile-time EDSL такое возможно
I>Теоретически возможно, но пока ничего работающего ни ты, ни alex_public не показали.
НС>Им интересен реальный рабочий инструмент. И linq2db таковым является в полный рост, а вот sqlpp — увы и ах.
Так я и не агитирую за sqlpp11, там вполне может чего-то не быть, что никак не является опровержением моих слов.
Re[183]: Тормознутость и кривость linq. Compile-time EDSL DB
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Я не знаю что ты называешь ad-hoc типами. Я даже отдельную тему с вопросом создал.
Тебе там вроде доходчиво ответили.
EP>Пример с макросом NEW был именно на Anonymous Type, и в другой теме.
Анонимные типы это реализация ad-hoc типов в C#, что непонятно то?
EP> Синтезирование же типов по месту реализуется в том числе и другими механизмами.
Чем, в твоем понимании, отличается "синтезирование тпов по месту" и анонимный тип с выражениями?
НС>>что сам запрос операцией проекции порождает новую "таблицу". Я ж ведь не зря говорил про простейший случай. Как вместо простой ссылки на поле таблицы нарисовалось выражение — уже какой то NEW вылез.
EP>Нет в моём примере никакого макроса NEW, он был в другой теме.
Он есть прямо по той ссылке, что ты сам сюда и притащил.
EP> Вот пример использования:
Опять самый примитивный. О чем и речь.
НС>>А если после операции проекции нам надо опять фильтр наложить? Сгруппировать? Еще одну проекцию добавить?
EP>auto q = from(foo).where(foo.id > 42_i).select(foo.value, foo.id).select(foo.number);
И это все богатство превратится в SQL полностью?
EP>Вот отформатированный вывод препроцессора:
Отож. А теперь посмотри на то, что генерирует шаблон linq2db — там обычные объекты, а не страшное чудовище. Суть этой генерации не в том чтобы нагенерить кучу говнокода, а в том чтобы генерить это из структуры БД.
НС>>Если это будет С++ для safe дотнета, то не особо меньше. А сравнивать алгоритмы с разными нефункциональными требованиями, причем сравнивать именно эти самые нефункциональные требования — чистейшая демагогия. EP>Есть задача написать алгоритм
Нет, задача в случае CodeJam шире. Нефункциональные требования, слышишь?
EP>А рассуждения о нефункциональности требований и т.п. это всё лирика.
А, ну ну.
НС>>А разве ты тут писал про то, что С++ в чем то хуже С#? Хотя бы пару раз? EP>Из текущего топика:
Ага, лямбды конечно лаконичнее, но С++ все равно лучше. ЧТД.
EP>Что такое "дженерик-арифметика", конкретно?
Использование арифметических и логических операторов в дженерик коде.
Дженерики, в отличие от плюсовых шаблонов, компилируются в бинарник именно в виде шаблонов. Поэтому вот так просто взять и использовать в нем операторы нельзя.
НС>>Та еще ржака смотреть, как ты с алексом рассказываете про то как надо правильно работать с БД Синклеру и ИТ. EP>А где я вообще сказал что я показываю как надо правильно работать с БД?
Весь этот топик вы тут убеждаете, что линк это гавно и неправильный подход.
EP>Я утверждаю что язык запросов времени компиляции с минимальным или нулевым overhead'ом вполне реализуем
Для частных случаев.
EP>Кто-то выше утверждает что это невозможно
Невозможно? Или непрактично?
EP>При этом не давал оценки реальной практической необходимости именно такого варианта.
А тебе постоянно указывают именно на непрактичность.
Re[183]: Тормознутость и кривость linq. Compile-time EDSL DB
EP>Нет, это у тебя проблемы со знанием предметной области. По моему опыту, в типичном ERP приложении примерно 90% запросов не содержат динамических ветвлений. Так что 1000 запросов это вообще ни о чем.
Те запросы, которые непосредственно пишут прикладники — те динамические в 10, может в 20% случаев. Но вот финальный запрос может быть динамическим в 100%. Понятно?
НС>>Понимаешь, твоих оппонентов не интересует возможность теоретически получить какой то результат в некоторых ситуациях. EP>За всех не говори. EP>Например они делают заявления о теоретической возможности/невозможности чего-то, с этим я и спорю. Например:
... I>>Теоретически возможно, но пока ничего работающего ни ты, ни alex_public не показали.
Re[184]: Тормознутость и кривость linq. Compile-time EDSL DB
Здравствуйте, Ночной Смотрящий, Вы писали:
EP>>Я не знаю что ты называешь ad-hoc типами. Я даже отдельную тему с вопросом создал. НС>Тебе там вроде доходчиво ответили.
Это их предположение, интерпретация, откуда мне знать совпадает ли она с твоей.
Вообще говоря anonymous не является синонимом ad-hoc — это какая-то отсебятина. Ad-hoc может быть совсем не анонимным.
EP>> Синтезирование же типов по месту реализуется в том числе и другими механизмами. НС>Чем, в твоем понимании, отличается "синтезирование тпов по месту" и анонимный тип с выражениями?
Тем что синтезируется именно анонимный тип, причём с вполне конкретной спецификой. При этом в общем случае по месту может синтезироваться какой угодно тип.
НС>>>что сам запрос операцией проекции порождает новую "таблицу". Я ж ведь не зря говорил про простейший случай. Как вместо простой ссылки на поле таблицы нарисовалось выражение — уже какой то NEW вылез. EP>>Нет в моём примере никакого макроса NEW, он был в другой теме. НС>Он есть прямо по той ссылке, что ты сам сюда и притащил.
Ну и что что он был по ссылке в каком одном из моих сообщений? Из этого не следует что он использовался в реализации, которая была совершенно в другой ветке
EP>> Вот пример использования: НС>Опять самый примитивный. О чем и речь.
А какой нужен? Более сложные варианты тоже возможны, и например есть в примерах sqlpp11.
НС>>>А если после операции проекции нам надо опять фильтр наложить? Сгруппировать? Еще одну проекцию добавить? EP>>auto q = from(foo).where(foo.id > 42_i).select(foo.value, foo.id).select(foo.number); НС>И это все богатство превратится в SQL полностью?
В первой же строчке вывода примера показан SQL:
SELECT foo.value, foo.id, foo.number FROM foo WHERE foo.id>42
EP>>Вот отформатированный вывод препроцессора: НС>Отож. А теперь посмотри на то, что генерирует шаблон linq2db — там обычные объекты, а не страшное чудовище.
В linq2db также и вспомогательный код
НС>Суть этой генерации не в том чтобы нагенерить кучу говнокода, а в том чтобы генерить это из структуры БД.
И там и там цель связать пользовательский код с БД. А сколько там строчек в текстовом шаблоне у кодогенератора — вообще не принципиально
НС>>>Если это будет С++ для safe дотнета, то не особо меньше. А сравнивать алгоритмы с разными нефункциональными требованиями, причем сравнивать именно эти самые нефункциональные требования — чистейшая демагогия. EP>>Есть задача написать алгоритм НС>Нет, задача в случае CodeJam шире. Нефункциональные требования, слышишь?
Конечно, не надо обрезать цитату:
EP>>Есть задача написать алгоритм, естественно нормальным способом, а не номинальным или абы-каким.
НС>>>А разве ты тут писал про то, что С++ в чем то хуже С#? Хотя бы пару раз? EP>>Из текущего топика: НС>Ага, лямбды конечно лаконичнее, но С++ все равно лучше. ЧТД.
У тебя с логикой проблемы? Где я это говорил? Мои слова:
Лямбды лаконичнее — да, реализация алгоритма — нет.
ВСЁ. Свои додумки оставляй при себе.
EP>>Что такое "дженерик-арифметика", конкретно? НС>Использование арифметических и логических операторов в дженерик коде. НС>Дженерики, в отличие от плюсовых шаблонов, компилируются в бинарник именно в виде шаблонов. Поэтому вот так просто взять и использовать в нем операторы нельзя.
Это звучит как очередная кривость языка/платформы, а не как принципиальное ограничение компиляции в бинарник как шаблона.
Чем операторы отличаются от других методов/функций?
НС>>>Та еще ржака смотреть, как ты с алексом рассказываете про то как надо правильно работать с БД Синклеру и ИТ. EP>>А где я вообще сказал что я показываю как надо правильно работать с БД? НС>Весь этот топик вы тут убеждаете, что линк это гавно и неправильный подход.
Опять ты врёшь. Где я это утверждаю?
EP>>Кто-то выше утверждает что это невозможно НС>Невозможно? Или непрактично?
"Невозможно" в том числе, и в том числе "теоретически".
Re[184]: Тормознутость и кривость linq. Compile-time EDSL DB
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>>>Понимаешь, твоих оппонентов не интересует возможность теоретически получить какой то результат в некоторых ситуациях. EP>>За всех не говори. EP>>Например они делают заявления о теоретической возможности/невозможности чего-то, с этим я и спорю. Например: НС>... I>>>Теоретически возможно, но пока ничего работающего ни ты, ни alex_public не показали. НС>
О, уже художественная резка по цитатам началась
Учу читать:
НС>>Понимаешь, твоих оппонентов не интересует возможность теоретически получить какой то результат в некоторых ситуациях. EP>За всех не говори. EP>
Например они делают заявления о теоретической возможности/невозможности чего-то, с этим я и спорю. Например:
EP>
G>>>Это api для более-менее типизированного построения примитивных запросов. Он не может никаким образом получить два разных запроса из одного и того же куска кода. Даже теоретически.
EP>>Это ещё почему? Например у него есть коннектор в БД, и к обычным контейнерам — один и тот же запрос может выполнять совершенно разные веши
EP>
EP>>>>>Тип в который в том числе закодировано дерево выражения. На C++ это реализуется с помощью техники Expression Templates, которой уже более двадцати лет.
G>>>>Показывай минимально работающий пример, который обходит дерево и строит SQL.
EP>>>Показывающий что конкретно? Проекции? Фильтры? Автоматические join'ы по связям?
G>>Фильтры и проекции, с джоинами потом разберемся
EP>>>Это всё ни одна сотня строк кода, реализовать которые мне не интересно.
G>>Тогда какой смысл в том, что ты пишешь? На практике никто такое не сделал, значит невозможно. Иначе уже была бы реализован аналог linq на C++.
Или например спрашивают про реализацию:
EP>
G>>1) Так ты покажи макрос conditional или что там у тебя. А то так можно любой код написать и объявить его "статическим".
G>>2) Как делать декомпозицию \ композицию таких запросов? В идеале так:http://blog.gandjustas.ru/2010/05/30/iqueryable-generics/
EP>
EP>>>Так и в случае с compile-time EDSL такое возможно
I>>Теоретически возможно, но пока ничего работающего ни ты, ни alex_public не показали.
Здравствуйте, gandjustas, Вы писали: G>Но я говорил не про кеш таблиц, а про кеш результатов запроса. Его почти нигде нет или тупо не используется, потому что нереально обеспечить его когерентность.
Я лет 15 назад читал про semantic caching, где между клиентом и сервером вклинивалась in-memory RDBMS, способная отвечать на запросы из кэша. Там прямо была продвинутая техника анализа, которая позволяла второй запрос выполнить без обращения на сервер:
select * from students where lastName = 'Smith';
select * from students where lastName = 'Smith' and age = 21;
При этом аналогичная логика трассировала предикаты в insert, update и delete, чтобы обсолетить результаты.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alex_public, Вы писали:
_>Гитхаб не репрезентативен, потому что на него не принято выкладываться целым областям индустрии. Кто-нибудь видел там выложенные исходники прошивок микроконтроллеров автомобиля, выкладываемого автоконцернами?
Да мы там даже код прошивки от Apollo 11 видели.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[185]: Тормознутость и кривость linq. Compile-time EDSL DB
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Вообще говоря anonymous не является синонимом ad-hoc
anonymous — реализация ad-hoc в конкретном языке.
EP>Ad-hoc может быть совсем не анонимным.
Смысла в неанонимности ad-hoc нет.
НС>>Чем, в твоем понимании, отличается "синтезирование тпов по месту" и анонимный тип с выражениями? EP>Тем что синтезируется именно анонимный тип, причём с вполне конкретной спецификой. При этом в общем случае по месту может синтезироваться какой угодно тип.
Ничего не понял.
EP>>>Нет в моём примере никакого макроса NEW, он был в другой теме. НС>>Он есть прямо по той ссылке, что ты сам сюда и притащил. EP>Ну и что что он был по ссылке в каком одном из моих сообщений?
По ссылке было вполне конкретное сообщение, где ты наглядно демонстрируешь, что без макросов сконструировать анонимный тип из выражений сложнее прямого обращения к полю не получается.
EP>>>auto q = from(foo).where(foo.id > 42_i).select(foo.value, foo.id).select(foo.number); НС>>И это все богатство превратится в SQL полностью? EP>В первой же строчке вывода примера показан SQL: EP>
EP>SELECT foo.value, foo.id, foo.number FROM foo WHERE foo.id>42
EP>
Это fail, потому что должно быть SELECT foo.number FROM ....
НС>>Отож. А теперь посмотри на то, что генерирует шаблон linq2db — там обычные объекты, а не страшное чудовище. EP>В linq2db также и вспомогательный код
Опять не распарсил. Нет там никакого вспомогательного кода кроме необязательной разметки атрибутами. Обычные POCO.
НС>>Суть этой генерации не в том чтобы нагенерить кучу говнокода, а в том чтобы генерить это из структуры БД. EP>И там и там цель связать пользовательский код с БД.
Нет. В твоем варианте есть еще одна цель — не писать руками кучу левого гавна, потому что руками такое никто в здравом рассудке писать не будет.
НС>>Ага, лямбды конечно лаконичнее, но С++ все равно лучше. ЧТД. EP>У тебя с логикой проблемы? Где я это говорил? Мои слова: EP>
EP>Лямбды лаконичнее — да, реализация алгоритма — нет.
ВСЁ. Свои додумки оставляй при себе.
Никаких додумок. В этой цитате С++ у тебя опять лучше всех. А я тебя просил привести пример обратного. Ты не смог. ЧТД.
НС>>Дженерики, в отличие от плюсовых шаблонов, компилируются в бинарник именно в виде шаблонов. Поэтому вот так просто взять и использовать в нем операторы нельзя. EP>Это звучит как очередная кривость языка/платформы
Это не просто звучит, это кривость и есть.
EP>Чем операторы отличаются от других методов/функций?
Тем что операторы не являются частью бинарного контракта экземпляра.
Re[186]: Тормознутость и кривость linq. Compile-time EDSL DB
Здравствуйте, Ночной Смотрящий, Вы писали:
EP>>>>Нет в моём примере никакого макроса NEW, он был в другой теме. НС>>>Он есть прямо по той ссылке, что ты сам сюда и притащил. EP>>Ну и что что он был по ссылке в каком одном из моих сообщений? НС>По ссылке было вполне конкретное сообщение,
По ссылке был лишь пример того, что я знаю что такое Anonymous Type. Зачем ты на него ссылаешься, учитывая то что я неоднократно приводил полный код примера в этой теме, где ничего подобного нет.
НС>где ты наглядно демонстрируешь, что без макросов сконструировать анонимный тип из выражений сложнее прямого обращения к полю не получается.
Нет, там я этого не демонстрирую. Это очередной логический fail
EP>>>>auto q = from(foo).where(foo.id > 42_i).select(foo.value, foo.id).select(foo.number); НС>>>И это все богатство превратится в SQL полностью? EP>>В первой же строчке вывода примера показан SQL: EP>>
EP>>SELECT foo.value, foo.id, foo.number FROM foo WHERE foo.id>42
EP>>
НС>Это fail, потому что должно быть SELECT foo.number FROM ....
Учу читать:
EP>Тут второй select добавляет колонку в проекцию, это конечно не совсем верно, но для демонстрации изменения проекции вполне подойдёт.
Переделать поведение на SELECT foo.number FROM ... не проблема
НС>>>Отож. А теперь посмотри на то, что генерирует шаблон linq2db — там обычные объекты, а не страшное чудовище. EP>>В linq2db также и вспомогательный код НС>Опять не распарсил. Нет там никакого вспомогательного кода кроме необязательной разметки атрибутами. Обычные POCO.
Смотри внимательней, я тебе дал прямую ссылку на сгенерированный код, там есть и исполняемый код.
НС>>>Ага, лямбды конечно лаконичнее, но С++ все равно лучше. ЧТД. EP>>У тебя с логикой проблемы? Где я это говорил? Мои слова: EP>>
EP>>Лямбды лаконичнее — да, реализация алгоритма — нет.
ВСЁ. Свои додумки оставляй при себе. НС>Никаких додумок. В этой цитате С++ у тебя опять лучше всех.
Почему?
НС>А я тебя просил привести пример обратного. Ты не смог. ЧТД.
Мне может покаяться нужно что я привёл пример zero overhead? Или то что указал на ненормальность ситуации такого количества boilerplate для простейшего алгоритма?
А то уже какие-то странные разговоры пошли, мол лямбдами как-то не так восхитился, с чем связан восторг и т.п.
Re[187]: Тормознутость и кривость linq. Compile-time EDSL DB
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>По ссылке был лишь пример того, что я знаю что такое Anonymous Type.
Нет, там был ответ на вопрос — как будут выглядеть твои типы в случае, когда там выражение, а не просто поле.
НС>>где ты наглядно демонстрируешь, что без макросов сконструировать анонимный тип из выражений сложнее прямого обращения к полю не получается. EP>Нет, там я этого не демонстрирую.
Ничего не понял. Тебе задали конкретный вопрос — что будет, если там выражение. Ты привел решение с макросами. А теперь выкручиваешься и стрелки переводишь.
EP>Переделать поведение на SELECT foo.number FROM ... не проблема
Уверен?
НС>>Опять не распарсил. Нет там никакого вспомогательного кода кроме необязательной разметки атрибутами. Обычные POCO. EP>Смотри внимательней, я тебе дал прямую ссылку на сгенерированный код, там есть и исполняемый код.
Где? Давай конкретно.
НС>>Никаких додумок. В этой цитате С++ у тебя опять лучше всех. EP>Почему?
Потому что там написано, что хоть у C# ситаксис лямбд и лаконичнее, но в целом С++ лучше. Классика жанра — любой аргумент дезавуировать "но в главном то он прав".
НС>>А я тебя просил привести пример обратного. Ты не смог. ЧТД. EP>Мне может покаяться нужно что я привёл пример zero overhead?
Не надо тебе каятся, просто надо признать что все что ты тут пишешь предельно однобоко. Надо быть слепым чтобы этого не замечать.
Re[188]: Тормознутость и кривость linq. Compile-time EDSL DB
Здравствуйте, Ночной Смотрящий, Вы писали:
EP>>По ссылке был лишь пример того, что я знаю что такое Anonymous Type. НС>Нет, там был ответ на вопрос — как будут выглядеть твои типы в случае, когда там выражение, а не просто поле.
Так а вопрос был по-твоему в ответ на что?
EP>>Что такое анонимные типы в C# я знаю, даже реализовывал
аналог на C++.
AVK>И что, там можно давать полям новые имена и использовать сложные выражения? Потому что примитивные варианты в примерах по ссылке это интересно, но практически не особо полезно. А примеров посложнее там нет.
НС>>>где ты наглядно демонстрируешь, что без макросов сконструировать анонимный тип из выражений сложнее прямого обращения к полю не получается. EP>>Нет, там я этого не демонстрирую. НС>Ничего не понял. Тебе задали конкретный вопрос — что будет, если там выражение. Ты привел решение с макросами.
Вопрос задали про тот конкретный пример.
EP>>Переделать поведение на SELECT foo.number FROM ... не проблема НС>Уверен?
НС>>>Опять не распарсил. Нет там никакого вспомогательного кода кроме необязательной разметки атрибутами. Обычные POCO. EP>>Смотри внимательней, я тебе дал прямую ссылку на сгенерированный код, там есть и исполняемый код. НС>Где? Давай конкретно.
Например в самом начале:
public ITable<AlphabeticalListOfProduct> AlphabeticalListOfProducts { get { return this.GetTable<AlphabeticalListOfProduct>(); } }
public ITable<Category> Categories { get { return this.GetTable<Category>(); } }
...
[FreeTextTableExpression]
public ITable<FreeTextKey<TKey>> FreeTextTable<TTable,TKey>(string field, string text)
{
return this.GetTable<FreeTextKey<TKey>>(
this,
((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)),
field,
text);
}
[FreeTextTableExpression]
public ITable<FreeTextKey<TKey>> FreeTextTable<TTable,TKey>(Expression<Func<TTable,string>> fieldSelector, string text)
{
return this.GetTable<FreeTextKey<TKey>>(
this,
((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)),
fieldSelector,
text);
}
...
Вполне соответствует как ты говоришь "куче левого гавна, потому что руками такое никто в здравом рассудке писать не будет."
НС>>>Никаких додумок. В этой цитате С++ у тебя опять лучше всех. EP>>Почему? НС> Потому что там написано, что хоть у C# ситаксис лямбд и лаконичнее, но в целом С++ лучше.
Я не говорил "в целом лучше".
Оппонент пытался оправдать раздутую реализацию лаконичностью использования на стороне вызова.
НС>Классика жанра — любой аргумент дезавуировать "но в главном то он прав".
Это вообще из другой оперы. Это про ложные высказывания на которых строится логический вывод "главного".
Здесь же оба факта верны: "Лямбды лаконичнее — да, реализация алгоритма — нет.".
А "в целом лучше" это уже твоя додумка.
НС>>>А я тебя просил привести пример обратного. Ты не смог. ЧТД. EP>>Мне может покаяться нужно что я привёл пример zero overhead? НС>Не надо тебе каятся, просто надо признать что все что ты тут пишешь предельно однобоко. Надо быть слепым чтобы этого не замечать.
Я развеиваю мифы о C++ и делюсь знаниями — язык старый, сменилось много поколений стилей и т.п. Некоторые основывают свои высказывания хорошо если на основе фактов 25-летней давности. То что я развеиваю мифы только о нём — не означает что я считаю его "лучше всех остальных языков" и т.п. Без проблем использую C#, о чём даже в этой теме говорил.
Местные оппоненты же (разумеется не все) воспринимают это как "ACHTUNG! ВРАГ В ТРЕДЕ" и начинают заваливать демагогией, передёргиваниями и враньём
Re[189]: Тормознутость и кривость linq. Compile-time EDSL DB
Это просто набор хелперных методов. К запросам они отношения не имеют. Первые два — просто шоткаты, последний это вообще какие то заморочки с полнотекстовым поиском.
НС>> Потому что там написано, что хоть у C# ситаксис лямбд и лаконичнее, но в целом С++ лучше. EP>Я не говорил "в целом лучше".
Ну алгоримическивыразительно лучше. Суть та же.
EP>Оппонент пытался оправдать раздутую реализацию лаконичностью использования на стороне вызова.
Что пытался тот оппонент оправдать вообще непонятно — он вообще постоянно какую то алогичную кашу на голову собеседникам вываливает. К нашему разговору это отношения не имеет.
НС>>Не надо тебе каятся, просто надо признать что все что ты тут пишешь предельно однобоко. Надо быть слепым чтобы этого не замечать. EP>Я развеиваю мифы о C++
Ага, особенно ты развеивал мифы, когда влез в топик обсуждения CodeJam в ихнем форуме и начал сравнивать С# со своим С++. Самому не смешно?