Re[64]: В России опять напишут новый объектно-ориентированны
От: Danchik Украина  
Дата: 09.05.18 16:52
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Danchik, Вы писали:


IT>Есть LINQ over WCF, в котором пересылается не expression tree, а SQL AST. При этом сам linq используется максимально полноценно. Попытка сериализовать/десериализовать expression tree однажды предпринималась определёнными интузизистами, но насколько мне известно закончилась ничем.


Черт его знает, это рекомендовали:
https://github.com/esskar/Serialize.Linq
Re[20]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 09.05.18 17:14
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, Sinclair, Вы писали:


S>>В нём всё еще трудно повторно использовать код — в частности, невозможно авто-типизировать методы, в которые мы хотим выносить интересные нам фрагменты.


НС>Можно пример?

Вот так — можно:
string lastName = "Zhou";
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<Contact> contacts = context.Contacts;

    var ordersQuery = from contact in contacts
                      where contact.LastName == lastName
                      select new { LastName = contact.LastName, Orders = contact.SalesOrderHeaders };

    foreach (var order in ordersQuery)
    {
        Console.WriteLine("Name: {0}", order.LastName);
        foreach (SalesOrderHeader orderInfo in order.Orders)
        {
            Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}",
                orderInfo.SalesOrderID, orderInfo.OrderDate, orderInfo.TotalDue);
        }
        Console.WriteLine("");
    }
}

Вот так — нет:
auto OrdersQuery(IQueryable<Contact> contacts, string lastName)
{
  return ordersQuery = from contact in contacts
                      where contact.LastName == lastName
                      select new { LastName = contact.LastName, Orders = contact.SalesOrderHeaders };
}

...

using (AdventureWorksEntities context = new AdventureWorksEntities())
{
   ObjectSet<Contact> contacts = context.Contacts;

   var ordersQuery = OrdersQuery(contacts, "Zhou");
   foreach (var order in ordersQuery)
    {
        Console.WriteLine("Name: {0}", order.LastName);
        foreach (SalesOrderHeader orderInfo in order.Orders)
        {
            Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}",
                orderInfo.SalesOrderID, orderInfo.OrderDate, orderInfo.TotalDue);
        }
        Console.WriteLine("");
    }
}

Придётся явно декларировать тип для вот этого вот {LastName, Orders}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: В России опять напишут новый объектно-ориентированны
От: Ночной Смотрящий Россия  
Дата: 09.05.18 18:07
Оценка: 2 (1)
Здравствуйте, Sinclair, Вы писали:

S>Вот так — нет:

S>
S>auto OrdersQuery(IQueryable<Contact> contacts, string lastName)
S>{
S>  return ordersQuery = from contact in contacts
S>                      where contact.LastName == lastName
S>                      select new { LastName = contact.LastName, Orders = contact.SalesOrderHeaders };
S>}


А зачем вот так вот в лоб? Можно чуть поуниверсальнее:

IQueryable<T> OrdersQuery<T>(this IQueryable<Contact> contacts, string lastName, Expression<Func<Contact, T>> selector)
...


И все прекрасно выводится.

S>Придётся явно декларировать тип для вот этого вот {LastName, Orders}


Но если очень хочется прям селектор зареюзать (что довольно странное желание, на мой вкус, селекторы крайне редко реюзаются), то не обязательно явно, можно и по месту (string LastName, IQueryable<SalesOrderHeader> Orders) OrdersQuery(...
Re[22]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.05.18 04:08
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Но если очень хочется прям селектор зареюзать (что довольно странное желание, на мой вкус, селекторы крайне редко реюзаются), то не обязательно явно, можно и по месту (string LastName, IQueryable<SalesOrderHeader> Orders) OrdersQuery(...

Не вполне понял вот этот фрагмент — можно более полный код? И на какой версии C# это работает?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: В России опять напишут новый объектно-ориентированны
От: Ночной Смотрящий Россия  
Дата: 10.05.18 05:16
Оценка:
Здравствуйте, Sinclair, Вы писали:

НС>>Но если очень хочется прям селектор зареюзать (что довольно странное желание, на мой вкус, селекторы крайне редко реюзаются), то не обязательно явно, можно и по месту (string LastName, IQueryable<SalesOrderHeader> Orders) OrdersQuery(...

S>Не вполне понял вот этот фрагмент — можно более полный код?
(string LastName, IQueryable<SalesOrderHeader> Orders) OrdersQuery(IQueryable<Contact> contacts, string lastName)
{
  return ordersQuery = from contact in contacts
                      where contact.LastName == lastName
                      select (contact.LastName, contact.SalesOrderHeaders);
}

...

// variant 1
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
   ObjectSet<Contact> contacts = context.Contacts;

   var ordersQuery = OrdersQuery(contacts, "Zhou");
   foreach (var order in ordersQuery)
    {
        Console.WriteLine("Name: {0}", order.LastName);
        foreach (SalesOrderHeader orderInfo in order.Orders)
        {
            Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}",
                orderInfo.SalesOrderID, orderInfo.OrderDate, orderInfo.TotalDue);
        }
        Console.WriteLine("");
    }
}

...

// variant 2
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
   ObjectSet<Contact> contacts = context.Contacts;

   var ordersQuery = OrdersQuery(contacts, "Zhou");
   foreach (var (lastName, orders) in ordersQuery)
    {
        Console.WriteLine("Name: {0}", lastName);
        foreach (SalesOrderHeader orderInfo in orders)
        {
            Console.WriteLine("Order ID: {0}, Order date: {1}, Total Due: {2}",
                orderInfo.SalesOrderID, orderInfo.OrderDate, orderInfo.TotalDue);
        }
        Console.WriteLine("");
    }
}


S> И на какой версии C# это работает?


7+
Re[62]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 10.05.18 05:25
Оценка:
Здравствуйте, IT, Вы писали:

_>>Если linq научится отправлять прямо свой код (включая пользовательские лямбды) для выполнения на сервер, то это будет уже совсем другая история. Но это опять же будет возможно только при появление у СУБД какого-то иного интерфейса, помимо SQL. О чём собственно и была изначальная дискуссия.


IT>В полной мере, это невозможно в принципе. Только если кастрировать linq максимально, включая не только соответствующие причиндалы, но и ручки-ножки, и голову, т.е. всё, что торчит. Проблема в том, что linq выражения, являясь полноценным кодом в терминах самого приложения, могут включать в себя фрагменты, уникальные только для этого приложения, о которых СУБД не имеет понятия.


Так в этом и есть весь смысл. ))) И да, текущие реализации этого похоже не могут, но это не значит, что оно невозможно в принципе.
Re[63]: В России опять напишут новый объектно-ориентированны
От: IB Австрия http://rsdn.ru
Дата: 10.05.18 08:25
Оценка: +1
Здравствуйте, alex_public, Вы писали:

_>Так в этом и есть весь смысл. ))) И да, текущие реализации этого похоже не могут, но это не значит, что оно невозможно в принципе.

Как вы себе это в принципе представляете?
Ну то есть, технически передать код приложения на сервер и даже выполнить его там, проблем действительно нет. Но какой в этом смысл? Кроме возможного синтаксического удобства, за которое придется расплачиваться усложнением сервера. Один фиг, сначала надо выбрать данные в терминах понятных хранилищу (чтобы это было эффективно/отказоустойчиво), а потом обработать их в прикладном коде.
Мы уже победили, просто это еще не так заметно...
Re[63]: В России опять напишут новый объектно-ориентированны
От: IB Австрия http://rsdn.ru
Дата: 10.05.18 08:35
Оценка: +2
Здравствуйте, Gt_, Вы писали:

S>>Во-первых, как справедливо заметил Иван, область применения "ручного привода" неуклонно снижается, по мере взросления индустрии.

Gt_>да ладно. бигдата — все в ручную, от транзакций и консистентности, до самопального бэкапа. в области олтп сейчас мода на микросервисы, там тоже все между сервисами в ручную делают.
О чем и речь. Бигдата, как индустрия, еще в ясли ходит. Как только повзрослеет, все это выпиливание лобзиком по вазелину забудут как страшный сон. Желание пионеров делать все в ручную понятно, но долго это не продлится, прогресс неумолим.
Мы уже победили, просто это еще не так заметно...
Re[67]: В России опять напишут новый объектно-ориентированны
От: IB Австрия http://rsdn.ru
Дата: 10.05.18 08:50
Оценка:
Здравствуйте, Gt_, Вы писали:

Gt_>по моему у монго идея атомарного сохранения документа, т.е. тот самый развесистый объект запихиваешь данные со всех таблиц рдбмс и получаешь в принципе годную во многих задачах схему.

Не во многих задачах, а только в одной. На каждую новую задачу (новый сценарий) надо делать новый документ, иначе и атомарность уйдет и с выборкой бедулька. Иными словами, ограничение атомарность только на уровне документа — очень серьезное, и очень сильно влияет на дизайн приложения в целом и подсистему хранения в частности.
А так да, пока во всех сценариях можно обойтись одним документом, все работает не плохо. Но опять же, в таких сценариях, монга ничем не отличается от Postgree или MSSQL с поддержкой JSON-а. ))
Мы уже победили, просто это еще не так заметно...
Re[29]: В России опять напишут новый объектно-ориентированны
От: vdimas Россия  
Дата: 10.05.18 09:12
Оценка: :)
Здравствуйте, Jester, Вы писали:

J><поскипано>

J>То есть, я не понял: системных программистов только на ВМ готовили, а на ПО — нет? Хм..

Акценты сильно разные.


J>Значит ли это, что под каждую конкретную задачу системный аналитик создаёт новую, неповторимую модель велосипеда, вместо того, чтобы взять и адаптировать одну из существующих моделей?


Откуда такая мысль?


J>Например, если существующие СУБД не устраивают, то системный аналитик пишет новую СУБД?


Новые СУБД появляются достаточно регулярно.


V>>"Прикладникам" такие фокусы не доступны, но прикладники и не разрабатывают движки БД, а обсуждалось именно это.

V>>Известный "мем" — это как если прикладник в Дельфи не нашёл нужный ТКомпонент, то задача не имеет решения. ))
J>Всё хорошо в меру.

Это и не оспаривалось.
Речь о принципиальной возможно вести разработку на любом из уровней — от системного до прикладного.
Тут специфика может играть рояль лишь в том, что под прикладной уровень и так достаточно бойцов (обычно), поэтому системщиков зачастую безальтернативно кидают на уровень "ядра", "платформы" и т.д.


J>Когда-то нужно и свой компонент написать, когда-то — взять что-то на стороне, а когда-то — плюнуть и найти другой путь решения задачи.


Это уже пошли банальности из области азов проектирования.


V>>Собсно, нигде в мире отдельных "низкоуровневых системщиков" не готовили и готовить никогда не будут. Любой "низкоуровневый системщик" во всём мире готовится исключительно как "системный аналитик" и никак иначе, потому что разработка "базы", "платформы" — это наиболее ответственная часть в современном IT, по понятной причине — ошибки на этом уровне чудовищно дорогие из-за эффекта масштабирования.

J>То есть, только ВМщик может стать "низкоуровневым системщиком", я правильно понял?

Может стать кто угодно при наличии желания. Я обратил внимание на подготовку будущего спеца "изкаробки" в ВУЗ-е.


J>Однако же, один запрос на разных базах (одной структуры), или даже на одной базе, но сделанный в разное время, может иметь разные планы.


Я именно об этом чуть ниже и рядом несколько раз писал.


J>Как ты предлагаешь на этапе компиляции (или когда вообще?) определять, какой из планов этого конкретного запроса будет наиболее оптимальным в каждом конкретном случае?


Предлагалось генерить оптимизированный код по оценке имеющихся планов в реальной обстановке.
Мн-во всех планов известно заранее.
Из-за своей специфической природы "запчасти" кода оценки планов и кода исполнения этих планов хорошо повторно применимы, т.е. не смотря на кажущуюся большую мощность мн-ва всех планов, представление сразу всего мн-ва их можно сделать достаточно компактным. В нижней оценке размер бинаря будет стремиться к простой сумме кода оценок скана по всем индексам всех таблиц, участвующих во всех запросах (потенциальных участвующих индексах, бо некоторые индексы реально могут не участвовать ни в одном потенциальном плане исполнения запросов), плюс сумма кода выполнения скана по этим же индексам/таблицам. В верхней оценке будет простая комбинаторика из всех этих оценок и сканов, но размер кода этой комбинаторики (сугубо ИМХО) должен быть относительно небольшим, бо тела этих методов будут состоять из простых вызовов готовых "кирпичиков", грубо если, то в каждом теле оценивается/сканируется 3-5 таблицы в среднем (в реальных приложениях из упомянутых предметных областей).


J>Реально же даже набор индексов может различаться от базы к базе, не только распределение данных.


Дык, суть-то в том, что метаинформация базы неразрывно связана с кодом приложения. Т.е. изменилась метаинформация базы — пересобрали приложение.


V>>Когда речь о компиляции алгоритма над константными структурами данных, то сами данные часто исчезают – превращаются тупо в код (раскрутка циклов и рекурсивных вызовов и всё это опять рекурсивно). Тем самым убирается еще один уровень интерпретирования над данными, который практически всегда есть даже в самой-пресамой нейтивной программе над неконстантными данными. Но мы-то говорим о константных данных, т.е. которые можно превращать в код (всё мн-во запросов и планов по ним).

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

Если ты когда-нибудь работал в 1C в режиме разработчика (конфигуратора по их терминологии), то примерно суть должна быть понятна.
С одним существенным отличием — не должно быть способов изменять схему/метаинформацию базы вне предполагаемой гипотетической системы.
Т.е. ты же не изменяешь файлы MS SQL сервака "мимо" самого сервака, а пользуешься только его ср-вами? Ну и вот...


V>>Или еще пример – во многих "больших" системах в избытке наличествуют данные справочного характера, причём, некоторые из этих данных меняются очень редко или не меняются никогда (для примера – виды ордеров, т.е. такие данные, которые бесполезно менять без изменений в коде, т.е. для данного состояния кода они, по-сути, не меняются). Т.е., хватает таблиц небольшого размера, которые можно считать эдаким способом подробного описания enum-ов, просто на стороне базы, а не на клиенте. Всю эту шелуху тоже можно убрать нафик из таблиц (убрать сами таблицы), тупо инлайня код с их участием. Подобных мелочей хватает, но они могут кардинально влиять на происходящее, делая ассоциации "бесплатными" — например, вместо ID такого enum в других таблицах можно хранить физическое смещение на структуру в сегменте константных данных скомпиллированного бинарника. И такий мелочей, стоит только ногтём подцепить, — овердохрена.


J>SCD — slowly changing dimensions? Или ты о том, что иногда называют "user dictionaries" и часто засовывают в одну-две таблицы (это просто сопоставление текстовой семантики какому-то числу, типа 1-накладная, 2-счет-фактура, и т.п.)? Если второе — мне не кажется, что это представляет большую проблему. Да, запросы становятся более объёмными, но сами эти таблицы весьма небольшие, поэтому с большой вероятностью постоянно висят в кэше данных.


Всё-равно динамика.
Сервер же не отличает таблицы, в которых могут быть изменения от тех, в которых не могут.
Но когда речь о статике, то понятие readonly/const/final и т.д. — рулит.


J>Не, на самом деле, тема достаточно интересна. Разумеется, Секвел вовсе не единственный свет в окошке, те же NoSQL базы вполне живут себе и здравствуют, но — при вполне определённых условиях.


Более того, я приводил рядом уже примеры от той же IBM (Informix 4GL), где нечто похожее УЖЕ реализовано, правда, не с той степенью "окончательного решения вопроса". ))

В общем, это развитие SQL-подобного языка в сторону языка "более общего назначения", плюс со временем всё больше развивается доля статически компиллируемого в этой системе. Когда-то большим шагом вперёд была тотальная генерация p-code, сейчас они уже умеют генерить прямо в нейтив. Но из-за особенностей системы типов этого языка всё-равно остаётся слишком много динамики. А она в подавляющем большинстве сценариев банально не нужна.


V>>Например, мне тут "напомнили", что в средней прикладной базе живёт пару тыс и более запросов. У меня и ответ давно имеется – там (грубо) 80% кода, считай, дублирует друг друга, а из оставшихся 20% половина является библиотечным слоем. Т.е. в случае компиляции дублирование исчезает и с библиотеками всяко получше, бо для статически собираемой системы объем данных свыше библиотек теоретически не ограничен – всё-равно в бинарь попадёт только используемое по-факту. Совсем другое дело для динамических систем, верно? Там особо не разбежишься с библиотеками.


J>Правильно я понимаю, что ты предлагаешь всегда использовать rule-based оптимизацию, и не использовать cost-based?


Про распространение константности с еще на этапе бета-редукции я упоминал прямо в том сообщении, на которое ты отвечаешь. )) Т.е., const-based оптимизация еще на этапе компиляции может отбрасывать заведомо неэффективные планы для конкретных запросов и уже известных для них констант-параметров, оставляя последующей динамической rule-based оценке лишь "хорошие" варианты. Про это тоже упоминалось более одного раза в этом обсуждении.

Ну и, навскидку, через всякие ключи компиляции (или атрибуты/прагмы для конкретных запросов) этим всем можно было бы управлять. Разве что на данном этапе обсуждения погружаться в такие подробности слишком рано, ИМХО, это как делить шкуру не убитого медведя.


J>Многовато будет запросов.


Фигня для современных систем и в сравнении с объемом кода современного динамического "исполнителя" запросов.


J>Один и тот же запрос, с помощью добавления/удаления предикатов и изменения сортировки можно превратить в сотню.


Пример с паттерн-матчингом в открытой vs закрытой системы типов уже приводился.
Разница выходит принципиальная/катастрофическая. ))
Re[10]: Проблемы современных СУБД
От: vdimas Россия  
Дата: 10.05.18 09:37
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>Нам надо построить отчёт "студент — средняя оценка по всем курсам". Какого класса будет элемент этого списка?


Такого и будет:
средняя_оценка_по_всем_курсам

А вообще — не принципиально.
В условиях вывода типов оперировать именем типа не обязательно.
Классика жанра — тот же Haskel.
Точным именем типа оперируют ну крайне редко, т.е. почти никогда.
Почти всегда оперируют базовыми типами, типами-генериками (т.е. незамкнутый тип плюс алиасы замыкающих типов-параметров), или же просто алиасами типов в конкретном scope.


S>В SQL это всё делается одним стейтментом. В ORM — это 2*N запросов на чтение и N на модификацию.


А на уровне ORM неплохо бы уметь одно превращать в другое, т.е. генерить сразу нужный запрос.


S>И это я ещё не говорю про false fails, когда мы обламываемся при записи из-за optimistic locking failure. Тогда нам снова приходится делать всю волынку сначала.


Это смотря какой запрос сгенерит ORM.
Вдруг он умееть "склеивать" пачку однотипных запросов в один, перечисляя требуемые некие ID в предикате выборки? ))
Re[44]: В России опять напишут новый объектно-ориентированны
От: vdimas Россия  
Дата: 10.05.18 09:55
Оценка: :)
Здравствуйте, Klikujiskaaan, Вы писали:

_>>Полностью согласен. Но это не я тут заявлял, что Linq отлично подходит для всех видов коллекций.

K>Ты кажется вообще не понимаешь, что такое linq и что с ним делать.

Какое это имеет отношение к вопросу о фичах инструмента?
Что может помешать когда-нить в будущем добавить в LINQ операторы рекурсивных ссылок, на манер современных диалектов SQL?
Re[64]: В России опять напишут новый объектно-ориентированны
От: Gt_  
Дата: 10.05.18 17:20
Оценка: -1 :)
S>>>Во-первых, как справедливо заметил Иван, область применения "ручного привода" неуклонно снижается, по мере взросления индустрии.
Gt_>>да ладно. бигдата — все в ручную, от транзакций и консистентности, до самопального бэкапа. в области олтп сейчас мода на микросервисы, там тоже все между сервисами в ручную делают.
IB>О чем и речь. Бигдата, как индустрия, еще в ясли ходит. Как только повзрослеет, все это выпиливание лобзиком по вазелину забудут как страшный сон. Желание пионеров делать все в ручную понятно, но долго это не продлится, прогресс неумолим.

эх Ваня, подучиться бы тебе. тем временем даже дата сайенс уходит от высокоуровневого SQL к гораздо более низкоуровневым R и python скриптам

Gt_
Re[68]: В России опять напишут новый объектно-ориентированны
От: Gt_  
Дата: 10.05.18 18:04
Оценка:
Gt_>>по моему у монго идея атомарного сохранения документа, т.е. тот самый развесистый объект запихиваешь данные со всех таблиц рдбмс и получаешь в принципе годную во многих задачах схему.
IB>Не во многих задачах, а только в одной. На каждую новую задачу (новый сценарий) надо делать новый документ, иначе и атомарность уйдет и с выборкой бедулька. Иными словами, ограничение атомарность только на уровне документа — очень серьезное, и очень сильно влияет на дизайн приложения в целом и подсистему хранения в частности.
IB>А так да, пока во всех сценариях можно обойтись одним документом, все работает не плохо. Но опять же, в таких сценариях, монга ничем не отличается от Postgree или MSSQL с поддержкой JSON-а. ))

да, сильно влияет на дизайн. но и плюшки заметно масштабней мсскл с json. потому под эти сценарии майкрософт выкатила azure sql, а не мсскл с json.
эти ключ значения реально позволил индустрии посмотреть на субд с другой стороны, в результате проглядываются по настоящему интересные гибриды:
https://blog.cloudera.com/blog/2017/04/apache-kudu-read-write-paths/

все та же идеология key-value, позволяющая обалденно масштабироваться, но уже явно проглядываются оракловые UNDO, REDO, оаркловое консистентное чтение ... скоро будет очень интересно.

Gt_
Отредактировано 10.05.2018 19:29 Gt_ . Предыдущая версия .
Re[19]: В России опять напишут новый объектно-ориентированны
От: alex_public  
Дата: 10.05.18 23:36
Оценка:
Здравствуйте, Sinclair, Вы писали:

_>>Кстати, я правильно понял, что ты под Linq подразумеваешь исключительно идею встраивания в язык SQL-подобного DSL, вне каких-либо привязок к определённым интерфейсам, языкам, платформам?

S>По большому счёту да.
S>То есть штука, которая сочетает преимущества статической типизации (и вытекающие из неё плюшки типа рефакторинга), возможностей по декомпозиции, и динамического исполнения.

Я в принципе совсем не против такого инструмента. Но есть пара нюансов:

— его реализацию всё же надо бы организовать без лишних рантаймовых накладных расходов
— если мы говорим о декларативном синтаксисе типа SQL, то он не кажется мне подходящим в качестве базового API к СУБД, в силу своей излишней высокоуровневости и как следствие ограниченности. Это не означает, что такой инструмент не нужен, просто если уж его делать, то как обёртку вокруг низкоуровневого API.

S>Современный linq уже лучше, чем тот же самый SQL, для работы с теми же RDBMS.


Ну в чём-то лучше, а в чём-то хуже (те же CTE с рекурсией).

S>В нём всё еще трудно повторно использовать код — в частности, невозможно авто-типизировать методы, в которые мы хотим выносить интересные нам фрагменты.

S>В нём всё ещё крайне трудно переносить вычисления на сторону сервера — те же самые агрегаты. В идеале, для них нужно что-то типа iterator pattern, только наоборот. То есть из кода типа
S>
S>public string Concatenate(IEnumerable<string> input, string delimiter = ", ")
S>{
S>  var s = string.Empty; // #1
S>  foreach(var i in input)
S>  {
S>    if (s.Length > 0) s+= delimiter; // #2
S>    s+=i;                            //
S>  }
S>  return s; // #3
S>} 
S>

S>мы автоматически порождаем код типа
S>
S>class __Concatenate__aggregate
S>{
S>  private string s; 
S>  public void Init()
S>  {
S>    this.s = string.Empty; // #1
S>  }

S>  public void Accumulate(string i, string delimiter = ", ")
S>  {
S>    if (s.Length > 0) s+= delimiter; // #2
S>    s+=i;                            //
S>  }

S>  public string Terminate()
S>  {
S>    return s; // #3
S>  }
 
S>  public void Merge(__Concatenate__aggregate value)
S>  {
S>    Accumulate(value.Terminate());
S>  }
S>}
S>

S>С попутными проверками на корректность — типа ассоциативности.

Код, понятный и кстати весьма похожий на известные реализации (типа того же Spark). Только вот непонятно причём тут вообще Linq — оба представленных фрагмента являются классическим императивным кодом, только немного по разному структурированному.

_>>Ну собственно я тоже сторонник МП, если можно так выразиться. Нюанс в том, что текущие реализации Linq построены по сути без него (убогая рефлексия — это явно не то, что можно называть МП). Более того, в самом мире .net эта парадигма совсем не популярна (см. на тот же Nemerle).

S>Я не вижу принципиальной разницы между compile-time и run-time МП.

Вообще то разница с рантаймовым МП очень большая, причём даже не в производительности, а в проверках на этапе разработки. Но Linq это не особо касается, т.к. там вообще странная схема. С одной стороны разбор происходит на этапе компиляции (это как бы плюс, т.к. позволяет проверки), а с другой МП там вообще не видно, т.к. превращение подготовленного компилятором AST в SQL — это уж точно не МП.

_>>PGO и т.п. — это конечно хорошо. Но я тебе уже не раз говорил, что это уже что-то вроде вишенки на торте. Т.е. в начале надо убедиться, что эффективно отработали все классические (статические) оптимизации, а уже потом можно задуматься об оптимизации под конкретные данные.

S>Всё как раз наоборот. По крайней мере там, где касается данных. Там семантические оптимизации важнее "статических". То есть способность, к примеру, обнаружить в метаданных check constraint вроде order_date > date(2018, 1,1) позволяет нам мгновенно вернуть результат запроса where order_date < date(2017, 12, 1). На фоне этого умение заинлайнить вызов date() при вычислении предиката вообще выглядит экономией на спичках — ну получим мы миллион вызовов вместо двух миллионов. Там, где можно было обойтись десятком вызовов.

Это ты говоришь уже не об оптимизации под конкретные данные (как в PGO), которая обычно вероятностная, а скорее о каких-то фундаментальных свойствах данных (ну типа отсортированности или ограничений сверху/снизу и т.п.), которые вообще должны закладываться программистом на уровне алгоритма.

_>>И что мешает добавить проверку и туда? )))

S>То, что указатель не оборудован длиной. В отличие от коллекции.

Вообще то мы тут говорили об уже не тривиальной коллекции (у которой в операторе [] заложена проверка) — с чего бы использовать в таком случае голый указатель, вместо своего типа итератора?

_>>Причём тут частичная специализация? Оно в любом случае превращается в int* для встроенных массивов.

S>Вот тут моих способностей проводить в уме частичные вычисления не хватает. Каким именно образом у нас iterator_type превращается в int*?

Так iterator_type — это же параметр шаблона и соответственно для range созданного вокруг встроенного массива (int[]) это будет просто int*.

_>>Ну перейдёт он и что? От этого не появятся новые накладные расходы в том месте, которое мы обсуждаем. Нас же интересует не разница в коде между int[] и vector<int> (которой кстати тоже частенько может не быть, но это тема совершенно другой беседы). Нам важно чтобы не было никакой разницы между тупым кодом с int[] и кодом с range вокруг int[], и точно так же не должно быть разницы между кодом с vector<int> и range вокруг vector<int>. В таком случае, мы говорим, что абстракция range имеет нулевой оверхед.

S>Ок. А какой тогда у этой абстракции смысл? Я его что-то перестал улавливать.

Смысл range? Как раз для того, чтобы удобным образом записывать различные операции с массивами (компоновать конвейер операций из элементарных). Приблизительно тоже самое, чем занимается Linq в реализации через IEnumerable, только удобнее (нет никаких проблем с заданием того же двоичного поиска), универсальнее (тот же произвольный доступ по коллекции спокойно работает) и эффективнее (никаких накладных расходов).

S>>>Давайте вообще реализуем коллекцию в виде односвязного списка из пар {key, value}, оператор [] у нас будет работать как {for(i=head;i!=null;i=i.next} if (i->key == key) return i->value; throw new index_out_of_range()}.

S>>>И оператор + мы определим точно так же — даже не будем вызывать уже готовый [], чтобы избежать лишнего потенциального вызова.
S>>>"Оверхед", конечно же, будет по-прежнему нулевым. При этом код будет, мягко говоря, не вполне оптимальным в среднем случае.
S>>>Поэтому я термин "оверхед" не люблю, и предпочитаю пользоваться терминами performance и abstraction penalty.
_>>Оверхед чего будет по прежнему нулевым? В твоём описание есть только некая специфическая коллекция и всё. Что с чем ты тут сравниваешь?
S>Я сравниваю O(1) c O(N). И не очень понимаю, зачем нам требовать одинаковости от операций адресной арифметики и операций индексации.

У кого O(N) в твоём примере я вижу. А у кого O(1) не вижу. Собственно я вообще не вижу в твоём примере никого кроме одной странной коллекции, так что совершенно не понятно кого с кем и для чего ты сравниваешь.
Re[24]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.05.18 05:12
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, Sinclair, Вы писали:


НС>>>Но если очень хочется прям селектор зареюзать (что довольно странное желание, на мой вкус, селекторы крайне редко реюзаются), то не обязательно явно, можно и по месту (string LastName, IQueryable<SalesOrderHeader> Orders) OrdersQuery(...

S>>Не вполне понял вот этот фрагмент — можно более полный код?
НС>[c#]
НС>(string LastName, IQueryable<SalesOrderHeader> Orders) OrdersQuery(IQueryable<Contact> contacts, string lastName)
НС>{
НС> return ordersQuery = from contact in contacts
НС> where contact.LastName == lastName
НС> select (contact.LastName, contact.SalesOrderHeaders);
НС>}
Ага, вы, наверное, имели в виду

IQueryable<(string LastName, IQueryable<SalesOrderHeader> Orders)> OrdersQuery(IQueryable<Contact> contacts, string lastName)
{
  return ordersQuery = from contact in contacts
                      where contact.LastName == lastName
                      select (contact.LastName, contact.SalesOrderHeaders);
}

В вашем примере возвращается скаляр.
Спасибо, интересная штука.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: В России опять напишут новый объектно-ориентированны
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.05.18 06:33
Оценка:
Здравствуйте, alex_public, Вы писали:
_>- его реализацию всё же надо бы организовать без лишних рантаймовых накладных расходов
Ещё раз: нас интересует производительность, а не накладные расходы. Грубо говоря, вы выжимаете константу при O(N), а меня интересует переход к O(Log Log N).

_>- если мы говорим о декларативном синтаксисе типа SQL, то он не кажется мне подходящим в качестве базового API к СУБД, в силу своей излишней высокоуровневости и как следствие ограниченности. Это не означает, что такой инструмент не нужен, просто если уж его делать, то как обёртку вокруг низкоуровневого API.

Это как раз потому, что вы не понимаете, что такое производительность. Чем сильнее мы зажимаем возможности языка, тем больше возможностей даём среде.
Между прочим, лучшие оптимизаторы за последние 50 лет были у Фортрана — как раз из-за его убогой выразительности.

_>Ну в чём-то лучше, а в чём-то хуже (те же CTE с рекурсией).

Ну, пока что их реализация в linq2db выглядит вполне пристойно.

_>Код, понятный и кстати весьма похожий на известные реализации (типа того же Spark). Только вот непонятно причём тут вообще Linq — оба представленных фрагмента являются классическим императивным кодом, только немного по разному структурированному.

При том, что мы будем использовать в linq выражениях агрегацию по вот такой функции, и она будет автоматически трансформироваться в server-side реализацию.

_>Вообще то разница с рантаймовым МП очень большая, причём даже не в производительности, а в проверках на этапе разработки. Но Linq это не особо касается, т.к. там вообще странная схема. С одной стороны разбор происходит на этапе компиляции (это как бы плюс, т.к. позволяет проверки), а с другой МП там вообще не видно, т.к. превращение подготовленного компилятором AST в SQL — это уж точно не МП.

Странно. Многие считают, что выполнение T4 шаблонов по результатам database query — это МП.

_>Это ты говоришь уже не об оптимизации под конкретные данные (как в PGO), которая обычно вероятностная, а скорее о каких-то фундаментальных свойствах данных (ну типа отсортированности или ограничений сверху/снизу и т.п.), которые вообще должны закладываться программистом на уровне алгоритма.

Нет. Всё наоборот: свойства должны закладываться на уровне данных, а алгоритм должен выбираться без участия программиста.
Потому что программистов, способных корректно применить хороший алгоритм — примерно в 1000 раз меньше, чем программистов, способных сказать "список, отсортируйся по алфавиту".

_>Вообще то мы тут говорили об уже не тривиальной коллекции (у которой в операторе [] заложена проверка) — с чего бы использовать в таком случае голый указатель, вместо своего типа итератора?

Вообще-то я говорил о минимальном типе "массив", и минимальном типе "указатель". Итератор — это вообще штука, у которой кроме оператора разыменования и инкремента может ничего и не быть.

_>Так iterator_type — это же параметр шаблона и соответственно для range созданного вокруг встроенного массива (int[]) это будет просто int*.

Вот тут я и не понимаю. В каком месте мы подставляем в шаблон этот параметр?

_>Смысл range? Как раз для того, чтобы удобным образом записывать различные операции с массивами (компоновать конвейер операций из элементарных). Приблизительно тоже самое, чем занимается Linq в реализации через IEnumerable, только удобнее (нет никаких проблем с заданием того же двоичного поиска), универсальнее (тот же произвольный доступ по коллекции спокойно работает) и эффективнее (никаких накладных расходов).

Ох-хох-хоо. Если бы авторы FCL хотели дать пользователям возможность стрелять себе в ноги, то никакой проблемы с заданием того же двоичного поиска бы и не было.
Точнее, их и так уже нет — вот вам BinarySearch: https://msdn.microsoft.com/en-us/library/system.array.binarysearch(v=vs.110).aspx, вот вам ArraySegment: https://msdn.microsoft.com/en-us/library/1hsbd92d(v=vs.110).aspx.
Extension Method для BinarySearch поверх ArraySegment пишется в две строки, после чего все вот эти вот цепочки upperBound и прочего пишутся на C# без напряжения.
_>У кого O(N) в твоём примере я вижу. А у кого O(1) не вижу. Собственно я вообще не вижу в твоём примере никого кроме одной странной коллекции, так что совершенно не понятно кого с кем и для чего ты сравниваешь.
В том-то и дело — оверхеда нет, а толку — чуть. Из этого мы делаем вывод, что полезность гонки за "отсутствием оверхеда" сильно преувеличена.
Надо гнаться не за оверхедом, а за производительностью. В частности, если у меня есть код, который тратит "лишнее" время на анализ предусловий, зато после этого выполняется за O(1), то мне неинтересен код с O(N^2), даже если в нём "оверхеда" строго ноль.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[25]: В России опять напишут новый объектно-ориентированны
От: Петрухин Эдуард Россия  
Дата: 11.05.18 08:05
Оценка:
Здравствуйте, Sinclair, Вы писали:
S>
S>IQueryable<(string LastName, IQueryable<SalesOrderHeader> Orders)> OrdersQuery(IQueryable<Contact> contacts, string lastName)
S>{
S>  return ordersQuery = from contact in contacts
S>                      where contact.LastName == lastName
S>                      select (contact.LastName, contact.SalesOrderHeaders);
S>}
S>

S>Спасибо, интересная штука.

К сожалению, не будет работать: «An expression tree may not contain a tuple literal.»
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[65]: В России опять напишут новый объектно-ориентированны
От: IB Австрия http://rsdn.ru
Дата: 11.05.18 10:32
Оценка:
Здравствуйте, Gt_, Вы писали:

Gt_>эх Ваня, подучиться бы тебе.

Учиться я всегда рад, было бы у кого и чему )

Gt_> тем временем даже дата сайенс уходит от высокоуровневого SQL к гораздо более низкоуровневым R и python скриптам

Вот тут сейчас теплое с мягким никто не попутал? Я тоже много умных слов знаю, но надо же их к месту употреблять ))
Тпипчный стек технологий (и путь данных) в DS выглядит следующим образом:
SOURCE -> STORE (вот тут SQL) -> CONVERT, TRANSFORM -> EXPLORE -> MODEL (вот здесь Python и R) -> VISUALISE -> PRODUCTION MANAGE (а здесь вообще, Java и C#)
Мы уже победили, просто это еще не так заметно...
Re[69]: В России опять напишут новый объектно-ориентированны
От: Ночной Смотрящий Россия  
Дата: 11.05.18 11:31
Оценка:
Здравствуйте, Gt_, Вы писали:

Gt_>да, сильно влияет на дизайн. но и плюшки заметно масштабней мсскл с json. потому под эти сценарии майкрософт выкатила azure sql, а не мсскл с json.


Azure SQL это и есть MSSQL, слегка подрихтованный. А для NoSQL там есть CosmosDB
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.