Здравствуйте, alex_public, Вы писали:
_>Это компилятор должен в процессе работы к базе обращаться? ) Иначе как ты отследишь все ошибки, если при работе с базой данных они возникают в основном в самой базе в динамике и зависят от структуры таблиц?
Что тебя смущает ? Ты же говорил, что метапрограммирование адски круто в С++, вот и продемонстрируй. Положим, для простоты, что структура базы в динамике не меняется.
Не нужно кода, общие вещи расскажи, как будут делаться. Скажем, в дотнете есть Expressions. Пишешь вот так
u = (from o in db.Orders select o.Total).Sum();
И все становится шоколадно. Переименовал колонку в базе — код компилироваться не должен. Переименовал свойство в коде — изменения можно применить и к базе, но, более того, все запросы которые дергают эту колонку должны или перестать компилироваться или должны пофикситься автоматически.
I>>Я не сильно в курсе, как проверить "нормальное удобство". Предложишь хороший тест ?
_>Не нужен тест. Мы просто фиксируем какой-то определённый уровень, относительно которого и будем дальше рассуждать. Т.е. нет абсолютной шкалы, но сравнить два конкретных языка и сказать какой из них удобнее в какой-то области вполне можно.
Так ты расскажи, что это за определенный уровень, шоб я мог его проверить и убедиться, что мне на нем так же удобно как и тебе.
_>А что не ясного? Если не учитывать области, где полезно применение метапрограммирования или же каких-то совсем низкоуровневых возможностей, то в остальном решения ня C++, C# и Java будут иметь довольно похожую структуру (в отличие от скажем решений на динамических языках). И соответственно удобство разработки будет довольно близким.
Это разве что в самых примитивных конструкциях — циклах на массиве каком. Управление ресурсами делается иначе, ОО-модель совершенно другая. Системный код пишется совершенно иначе, и тд и тд и тд.
I>>Питон давно уже перерос стадию скриптов и небольших проектов. Для орды индусов дотнет и джава слишком сложные.
_>Сложный проект без статической типизации? Да ну нафиг такой мазохизм...
"А посоны то и не знают " @
I>>Вообще то на питоне. Причины я уже указал. Как видишь, эти самые причины кроются совсем не в производительности.
_>Ну давай пруфлинк тогда. )
Здравствуйте, Ikemefula, Вы писали:
_>>Это компилятор должен в процессе работы к базе обращаться? ) Иначе как ты отследишь все ошибки, если при работе с базой данных они возникают в основном в самой базе в динамике и зависят от структуры таблиц?
I>Что тебя смущает ? Ты же говорил, что метапрограммирование адски круто в С++, вот и продемонстрируй. Положим, для простоты, что структура базы в динамике не меняется. I>Не нужно кода, общие вещи расскажи, как будут делаться. Скажем, в дотнете есть Expressions. Пишешь вот так
I>
I>u = (from o in db.Orders select o.Total).Sum();
I>
I>И все становится шоколадно. Переименовал колонку в базе — код компилироваться не должен. Переименовал свойство в коде — изменения можно применить и к базе, но, более того, все запросы которые дергают эту колонку должны или перестать компилироваться или должны пофикситься автоматически.
Linq2Sql? почему у меня при переименовании код все равно компилируется?
Здравствуйте, night beast, Вы писали:
I>>И все становится шоколадно. Переименовал колонку в базе — код компилироваться не должен. Переименовал свойство в коде — изменения можно применить и к базе, но, более того, все запросы которые дергают эту колонку должны или перестать компилироваться или должны пофикситься автоматически.
NB>Linq2Sql? почему у меня при переименовании код все равно компилируется?
Здравствуйте, Ikemefula, Вы писали:
I>>>И все становится шоколадно. Переименовал колонку в базе — код компилироваться не должен. Переименовал свойство в коде — изменения можно применить и к базе, но, более того, все запросы которые дергают эту колонку должны или перестать компилироваться или должны пофикситься автоматически.
NB>>Linq2Sql? почему у меня при переименовании код все равно компилируется?
I>Потому, что надо и маппинг обновлять.
дык как я тебя понял, "оно само" должно обновляться. а тут оказывается, что не само. ты уж определись.
а если учесть что коннекшн вообще из конфига может браться, вообще интересно получается.
Здравствуйте, exalicygane, Вы писали:
E>Для сферического писькомерства — да, можно сказать "С++ круче", но вам за что деньги платят? За промышленный код, мэйнстрим. И по-моему, вполне очевидно, что нарезка овощей на тёрке (C#) намного быстрее и безопаснее, чем их рубка саблей (С++). Нет никакого "превосходства" С++, если помимо самого алгоритма ты должен держать в голове выкрутасы С++. Про синтаксис вообще молчу — мрак второго уровня (после Перла и Хаскеля).
Перл ещё ладно, а хаскель-то чем провинился?
Пользовательскими операторами, что ли? Так они ничем не хуже фортрановско-сишных сокращений вида cblas_cgbmv или дотнетовско-явовских theKingdonOfNounsMethodNamig.
Если уж катить бочку на синтаксис, это надо APL/J/K вспомнить (как конкурент перлу) и окамл (конкурент плюсам по разнообразию фич).
Здравствуйте, Ikemefula, Вы писали:
I>Что тебя смущает ? Ты же говорил, что метапрограммирование адски круто в С++, вот и продемонстрируй. Положим, для простоты, что структура базы в динамике не меняется.
Так ты не ответил, компилятор должен лазить в базу данных или нет? ) Если да, то тогда действительно на C++ такое не реально (кстати, а вот на D вполне реализуемо). Если же нет, и ты всё же задаёшь соответствие названий колонок каким-то сущностям в коде где-то в другом месте кода, то это буквально есть в том же COCI.
I>Не нужно кода, общие вещи расскажи, как будут делаться. Скажем, в дотнете есть Expressions. Пишешь вот так I>
I>u = (from o in db.Orders select o.Total).Sum();
I>
Что-то мне не очень нравится такая запись. От неё складывается визуальное ощущение, что мы запрашиваем у базы не сумму по полю Total, а запрашиваем список значений Total и потом у себя суммируем.
I>Так ты расскажи, что это за определенный уровень, шоб я мог его проверить и убедиться, что мне на нем так же удобно как и тебе.
Так не важно что это за уровень. ))) Назовём его "уровень удобства C++" и будем рассуждать про другие языки, в каких он выше, а в каких ниже или равен. Понятна мысль? )
I>Это разве что в самых примитивных конструкциях — циклах на массиве каком. Управление ресурсами делается иначе, ОО-модель совершенно другая. Системный код пишется совершенно иначе, и тд и тд и тд.
Это внутри оно другое, а код похожий выходит (если конечно не использовать в C++ самые мощные и сложные возможности).
I>у него реп на соурсфордже
Ах вот ты про что...
Ну для начала надо читать внимательнее — у меня стоит не BitTorrent (который во-первых старый проект, а во-вторых вообще мне не нужен), а BitTorrent Sync (который вышел только в этом году и является весьма полезной штучкой).
Ну и потом даже сам BitTorrent написан на C++, а версия на Питоне — это самый первый прототип 10-и летней давности, который уже давно переписали. И кстати в отличие от прототипа это всё не Open source... )
Здравствуйте, alex_public, Вы писали:
I>>Что тебя смущает ? Ты же говорил, что метапрограммирование адски круто в С++, вот и продемонстрируй. Положим, для простоты, что структура базы в динамике не меняется.
_>Так ты не ответил, компилятор должен лазить в базу данных или нет? ) Если да, то тогда действительно на C++ такое не реально (кстати, а вот на D вполне реализуемо). Если же нет, и ты всё же задаёшь соответствие названий колонок каким-то сущностям в коде где-то в другом месте кода, то это буквально есть в том же COCI.
Задавай как угодно, главное что бы запросы были все до одного типизироваными.
I>>Не нужно кода, общие вещи расскажи, как будут делаться. Скажем, в дотнете есть Expressions. Пишешь вот так I>>
I>>u = (from o in db.Orders select o.Total).Sum();
I>>
_>Что-то мне не очень нравится такая запись. От неё складывается визуальное ощущение, что мы запрашиваем у базы не сумму по полю Total, а запрашиваем список значений Total и потом у себя суммируем.
Это неправильное ощущение.
I>>Так ты расскажи, что это за определенный уровень, шоб я мог его проверить и убедиться, что мне на нем так же удобно как и тебе.
_>Так не важно что это за уровень. ))) Назовём его "уровень удобства C++" и будем рассуждать про другие языки, в каких он выше, а в каких ниже или равен. Понятна мысль? )
В таком случае мне этот уровень удобства крайне неудобен.
I>>Это разве что в самых примитивных конструкциях — циклах на массиве каком. Управление ресурсами делается иначе, ОО-модель совершенно другая. Системный код пишется совершенно иначе, и тд и тд и тд.
_>Это внутри оно другое, а код похожий выходит (если конечно не использовать в C++ самые мощные и сложные возможности).
Это заблуждение. Сиплюсники бывает годами не могут перестроиться под дотнет.
_>Ну и потом даже сам BitTorrent написан на C++, а версия на Питоне — это самый первый прототип 10-и летней давности, который уже давно переписали. И кстати в отличие от прототипа это всё не Open source... )
Здравствуйте, Ikemefula, Вы писали:
I>Задавай как угодно, главное что бы запросы были все до одного типизироваными.
В общем, если мы всё равно задаём имена колонок руками где-то в коде, то я не вижу никакой разницы.
I>>> u = (from o in db.Orders select o.Total).Sum();
_>>Что-то мне не очень нравится такая запись. От неё складывается визуальное ощущение, что мы запрашиваем у базы не сумму по полю Total, а запрашиваем список значений Total и потом у себя суммируем.
I>Это неправильное ощущение.
Я в курсе. ))) Но внешне оно выглядит именно так. ))) Так что на мой взгляд гораздо очевиднее выглядит строка вида:
db<<"select sum(Total) from Orders", into(u);
I>В таком случае мне этот уровень удобства крайне неудобен.
Это не имеет значения, пока ты не сравниваешь с другими языками. Я к примеру тоже не в особом восторге от синтаксиса C++, но как бы лучше то всё равно нет из мейнстримовых. Вот только надежда что D всё же взлетит...
I>И он такой же кроссплатформенный ?
Здравствуйте, night beast, Вы писали:
I>>Потому, что надо и маппинг обновлять.
NB>дык как я тебя понял, "оно само" должно обновляться. а тут оказывается, что не само. ты уж определись.
Само это значит небольшой кусок кода автоматизирует всю ручную работу. С маппингами все так и есть — тебе не надо мотаться по коду и искать, где какая колонка может использоваться.
NB>а если учесть что коннекшн вообще из конфига может браться, вообще интересно получается.
Коннекшн всегда из конфига берётся и никаких проблем с этим не бывает.
Здравствуйте, Ikemefula, Вы писали:
I>>>Потому, что надо и маппинг обновлять.
NB>>дык как я тебя понял, "оно само" должно обновляться. а тут оказывается, что не само. ты уж определись.
I>Само это значит небольшой кусок кода автоматизирует всю ручную работу. С маппингами все так и есть — тебе не надо мотаться по коду и искать, где какая колонка может использоваться.
не вижу принципиальных ограничений генерировать то же самое на плюсах.
NB>>а если учесть что коннекшн вообще из конфига может браться, вообще интересно получается.
I>Коннекшн всегда из конфига берётся и никаких проблем с этим не бывает.
Здравствуйте, night beast, Вы писали:
I>>Само это значит небольшой кусок кода автоматизирует всю ручную работу. С маппингами все так и есть — тебе не надо мотаться по коду и искать, где какая колонка может использоваться.
NB>не вижу принципиальных ограничений генерировать то же самое на плюсах.
Принципиальные ограничения в работе с такими маппингами. Для этого нужны деревья выражений и их поддержка в языке.
NB>>>а если учесть что коннекшн вообще из конфига может браться, вообще интересно получается. I>>Коннекшн всегда из конфига берётся и никаких проблем с этим не бывает. NB>из конфига в смысле в рантайме.
Здравствуйте, Ikemefula, Вы писали:
I>>>Само это значит небольшой кусок кода автоматизирует всю ручную работу. С маппингами все так и есть — тебе не надо мотаться по коду и искать, где какая колонка может использоваться.
NB>>не вижу принципиальных ограничений генерировать то же самое на плюсах.
I>Принципиальные ограничения в работе с такими маппингами. Для этого нужны деревья выражений и их поддержка в языке.
принципиальные ограничения мы выдумываем себе сами.
сформировать запрос по автоматически сгенерированным типам -- задача вполне реальная.
NB>>>>а если учесть что коннекшн вообще из конфига может браться, вообще интересно получается. I>>>Коннекшн всегда из конфига берётся и никаких проблем с этим не бывает. NB>>из конфига в смысле в рантайме.
I>Именно так.
Здравствуйте, Ikemefula, Вы писали:
I>>>Само это значит небольшой кусок кода автоматизирует всю ручную работу. С маппингами все так и есть — тебе не надо мотаться по коду и искать, где какая колонка может использоваться. NB>>не вижу принципиальных ограничений генерировать то же самое на плюсах. I>Принципиальные ограничения в работе с такими маппингами. Для этого нужны деревья выражений и их поддержка в языке.
Если работа с фиксированными типами, поля которых известны в compile-time — то нужно только от-рефлектить поля а-ля Boost.Serialization/Fusion, или ODB:
odb::sqlite::database db ("people.db");
person john ("john@doe.org", "John Doe", 31);
person jane ("jane@doe.org", "Jane Doe", 29);
odb::transaction t (db.begin ());
db.persist (john);
db.persist (jane);
typedef odb::query<person> person_query;
for (person& p: db.query<person> (person_query::age < 30));
cerr << p << endl;
jane.age (jane.age () + 1);
db.update (jane);
t.commit ();
Деревья выражений в C++ уже лет 18 реализуются, причём их можно обходить и оптимизировать в compile-time
Если имя поля никак не связанно с типом, то можно использовать:
db.query<person>( ID("age") < 30 )
но — твоё дерево выражения в C# задаётся в compile-time, значит имя всё-таки известно, тогда всё что нужно это:
DEFINE_ID(age)
// ...
db.query<person>( age < 30 )
Здравствуйте, night beast, Вы писали:
NB>принципиальные ограничения мы выдумываем себе сами. NB>сформировать запрос по автоматически сгенерированным типам -- задача вполне реальная.
А что, где ты было сказано что это нереальная задача ?
Покажи пример, хотя бы вот такой пример order.Select(x => x.Total)
Такие вещи почти не встречаются. Обычно чтото сложнее, например так — order.Where(x => x.State == State.Closed).Select(x => x.Total)
А еще интереснее вот так — order.Where(Filter).Select(x => x.Total), где фильтр это почти обычная фукнция.
NB>>>из конфига в смысле в рантайме.
I>>Именно так.
NB>в рантайме маппинг генерируешь? ну-ну.
Где он генерируется, не важно. Важно, что это делается не руками.
Здравствуйте, Ikemefula, Вы писали:
I>Правильно понимаю, ты собираешься пропатчить компилятор, что бы он умел деревья выражений ?
I>Забудем пока про query comprehension.
I>Покажи, как ты собираешься вот такое реализовывать
I>Select(x => x.Total)
I>Здесь нечто, похожее на лямбду, на самом деле не лямбда, а языковая фича которая в С++ не поддерживается — Expression TreeПокаж.
I>Покажи аналог на С++
Ты снова описываешь решение, а не задачу. Давай задачку и там посмотрим как её оптимально решить. Пока что ты просил универсальный доступ к базам данных. Я тебе показал красивый и удобный универсальный вариант. Давай, покажи что теперь ещё хочешь...)))
Здравствуйте, alex_public, Вы писали:
_>универсальный доступ к базам данных. Я тебе показал красивый и удобный универсальный вариант. Давай, покажи что теперь ещё хочешь...)))
А все-таки, что с моим вопросом: http://rsdn.ru/forum/philosophy/5366518.1
Здравствуйте, Ikemefula, Вы писали:
EP>>Деревья выражений в C++ уже лет 18 реализуются, причём их можно обходить и оптимизировать в compile-time I>Реализуются, при этом сложность реализации либы на порядок выше, чем в дотнете.
Для compile-time обработки выражений есть Boost.Proto — он берёт большую часть работы на себя.
Но, деревья выражений можно строить и в runtime — там вообще нет ничего сложного
Здравствуйте, alex_public, Вы писали: _>Давай задачку и там посмотрим как её оптимально решить.
Вот мы пишем
using (var db = new DataContext())
{
var products = db
.Products
.Take(5)
.ToArray();
}
Для этого кода безразлично, какая СУБД используется — Oracle, MySQL, MS SQL и т.д.
То есть при запуске, если в ConnectionString:
a) прописана база MS SQL, то сгенерируется соответствующий SQL вида SELECT TOP 5 * FROM Products
б) прописан MySQL, то сгенерируется SQL вида SELECT * FROM Products LIMIT 5
в) ...
Таким образом, задача вообще не писать SQL руками, а простой сменой 1 строчки в конфиг файле перейти на другую СУБД.