Здравствуйте, alex_public, Вы писали:
_>В приведённым (не мною) примере Linq код работал через yield.
И что? Это частный случай. linq даже к IEnumerable не привязан.
НС>>И да, на уровне IL никаких сопрограмм нет в природе, а инлайнит сейчас JIT, которому на входе приходит как раз IL. _>Так а компилятор вообще не инлайнит?
Да, вообще не инлайнит.
_>>>Эмм, мы точно об одном и том же говорим? Ты считаешь, что работа с графами (дерево — это частный случай) может быть удобно реализована в рамках Linq? ))) НС>>Вполне. А что может помешать? _>А как там у linq с заданием рекурсий, всё удобно? )
Так же как у императивного кода.
Re[41]: В России опять напишут новый объектно-ориентированны
Здравствуйте, vdimas, Вы писали:
V>А по английски с NULL не сравнивают, говорят IS NULL.
Тут же вроде не в английском дело, а в том что с NULL сравнить нельзя в терминах SQL: нельзя сравнить два отсутствующих значения.
V>Чему равно выражение (NOT NULL)? ))
Там скорее (IS NOT) (NULL), а не (IS) (NOT (NULL)), по вышеописанным причинам.
ARI ARI ARI... Arrivederci!
Re[43]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Ночной Смотрящий, Вы писали: НС>Это вряд ли. Оно изначально проектировалось для бухгалтеров всяких, поэтому у него такой идиотский синтаксис.
Ок, я неверно выразился. RDBMS и вообще идея выражать запросы декларативными выражениями реляционной алгебры подходит для профессионалов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
В России опять напишут новый объектно-ориентированны
Здравствуйте, alex_public, Вы писали: _>Ну linq то тут в любом случае проиграл бы, просто из-за тормознутости сопрограмм, необходимости копирования и т.п. Теоретически — нет. Ничто не мешает потенциальному компилятору породить оптимальный код — наоборот, ему это сделать проще, чем в случае чисто императивного решения, т.к. намерение и механизм его реализации явно разделены.
Я практически уверен, что если мы попробуем записать точно такой же код на cовременном C++ (с лямбдами и прочим), то результат будет неотличимым от ручного выписывания циклов for.
Потому, что компиляторы C++ построены с применением агрессивного инлайнинга, а дальше SSA, сonstant propagation, и moving subexpression out of loop делают свою работу.
То есть "тормознутость сопрограмм" — это ограничения JIT по инлайнингу кода. "необходимость копирования" — это как раз из-за того, что инлайнинг не случился, и нет возможности передвинуть подвыражение.
Ещё раз подчеркну: декларативность linq к этому никакого отношения не имеет. Абсолютно императивный код, написанный на современном шарпе и обработанный современным джитом, подвержен ровно тем же затруднениям.
_>Это в любой задаче из данной области. А вот в данной конкретной задаче (где у нас вложенные коллекции и условие по предыдущему элементу) появился ещё и дополнительный алгоритмический провал. _>Конечно. Но если ты будешь вставлять условия фильтрации грубо говоря не в блоке where, а внутри некой своей дополнительной функции, генерирующей пары, то это будет по сути уже не linq, а тот же самый императивный код.
Нет, я не буду вставлять условия фильтрации внутри дополнительной функции.
Я сначала натравлю на коллекцию коллекций функцию, вычисляющую атрибут, а уже потом выполню PairScan:
from pair in (from c in collectionsList select new {c, count=(from i in c where i > 2).Count()}).PairScan() where ... select ...
Но это, по сути, беспредметный разговор. На всякий случай напомню, что код с Lag и прочим прекрасно компилируется в SQL, а его уже исполняет движок СУБД, способный радикальнейшим образом переставить порядок операций.
Это означает, что потенциально мы можем заменить все эти примитивные версии операторов Where и Select на их ExpressionTree-аналоги, а в методы ToList и GetEnumerable() встроить полноценный компилятор, способный выполнять агрессивный инлайнинг делегатов и оптимизацию циклов.
Более того, мы можем сделать так, чтобы вся эта адская магия срабатывала только тогда, когда у нас количество элементов в коллекции больше порогового, потому что на сотне элементов все эти вот "втрое медленнее" будут незаметны даже в микроскоп.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alex_public, Вы писали:
_>Эм, я так понимаю, ты тут подразумеваешь, что мы ручками делаем подобные запросы на все сервера и потом так же ручками их объединяем?
Нет, я подразумеваю, что взрослые RDBMS с Enterprise-лицензией сами раскидывают такие запросы по linked-серверам и собирают результаты автоматически. _>Да, и деление таблички у нас конечно же тоже руками, а не автоматическое, так? )
Нет, вполне себе автоматическое, по partition key.
_>Так "на лету" — это внутри запроса или же админом в консоли СУБД? )))
Нет никакой разницы между "консолью СУБД" и "исполнением запроса".
Можно взять, скажем, link2db, и обучить его при встрече неожиданной aggregate-функции выполнять сериализацию её в отдельную сборку при помощи Mono.Cecil, засовывать эту сборку в сервер через create assembly from <assemblyBytes> и регистрировать агрегат при помощи create aggregate.
Всё это занимает меньше времени, чем прочитать этот абзац вслух, и даже меньше, чем потребуется на исполнение запроса, даже в первый раз. А последующие исполнения будут полагаться на наличие уже зарегистрированного агрегата.
_>Собственно в чистом виде оно априори не повторяется в реляционной модели. Только с добавлением лишних сущностей (типа столбца id, задающего внешнюю коллекцию).
Ну, то есть кода не будет. Ок, жаль, а я так надеялся на конструктивную дискуссию.
S>>Какого-то нетривиального кода на Монге, где она пользуется "глобальной" переменной, и при этом работает корректно. А я попробую запустить аналог на моём ноуте на SQL Server Express 2017
_>Ну например тут https://docs.mongodb.com/manual/reference/operator/aggregation/redact/#pipe._S_redact есть примеры с переменными (правда системными, а не пользовательскими, но не суть).
Простите, это булшит. В данном примере используются просто как именованные константы, чтобы объяснить движку, что дальше делать. Цитирую:
The argument can be any valid expression as long as it resolves to $$DESCEND, $$PRUNE, or $$KEEP system variables. For more information on expressions, see Expressions.
Выделение — моё.
Если это тонкое место не вполне понятно, то вот пример кода:
В мире типизированных языков это было бы просто enum-ом, и redact() обязан был бы вернуть что-то из Traverse.Descend, Traverse.Keep. Traverse.Prune.
Попробуйте ещё раз. Предупреждаю: это сложнее, чем кажется. Скорее всего, первая попытка написать агрегацию с использованием глобальной переменной будет некорректной.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[41]: В России опять напишут новый объектно-ориентированны
Здравствуйте, alex_public, Вы писали: _>Стандарт на язык SQL оказывается уже воображаемый? )))
Ах, вы хотите перевести разговор на стандарт? Это тупиковая ветка дискуссии: для Монго никакого стандарта вообще не существует, так что этот забег она проиграет ещё до начала.
_>Ещё раз: хранимые процедуры — это не SQL. Это процедурный (императивный) язык, в то время как SQL является полностью декларативным языком.
Стесняюсь спросить: с чего вы это взяли?
Если уж вы хотите поговорить о стандартном SQL, то шокирующим откровением для вас станет часть четвёртая нынешнего ISO стандарта. И вообще, https://en.wikipedia.org/wiki/SQL/PSM:
Initially published in 1996 as an extension of SQL-92 (ISO/IEC 9075-4:1996, a version sometimes called PSM-96 or even SQL-92/PSM[2]), SQL/PSM was later incorporated into the multi-part SQL:1999 standard, and has been part 4 of that standard since then
То есть хранимые процедуры, внезапно, являются частью стандарта SQL уже больше 20 лет.
_>Я что-то не понял, это вот ты сейчас реально пытаешься снова проводить сравнение между MongoDB запросом без индекса и SQL запросом с индексом? Ты серьёзно считаешь, что настолько убогая демагогия может пройти? )))
При чём тут демагогия? Show me the code. Монга свой код написала. SQL свой код написал. SQL не виноват, что монга именно этот код не может эффективно исполнить. А SQL может эффективно исполнить именно этот код.
Не переписанный умным программистом, не оптимизированный под специфическую структуру данных, а прямо вот такой вот код, который написан 1-в-1 с технического задания: "сравнить MD5-код от имени пользователя с переданным из приложения значением".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[43]: В России опять напишут новый объектно-ориентированны
Здравствуйте, alex_public, Вы писали: _>Ну так а программист с for просто потратит чуть больше времени на добавление индекса и опять же получит большее быстродействие.
А потом статистика данных изменится, и программисту с for опять потребуется больше времени на добавление индекса.
_>Это всё конечно правильно, для многих усреднённых случаев. Однако это не отменяет того факта, что данная логика перестаёт работать в двух случаях: _>- в ряде не тривиальных задач, когда на sql/linq просто проблематично записать требуемое
Пока что мы таких задач не обнаружили. В обсуждённых примерах "проблематично" сводится к "я не владею linq/sql, поэтому мне проблематично написать код на них". _>- когда требуется максимально возможная производительность
Это да. Но "максимально возможная производительность" — это эдакая странная штука. Бескомпромиссное её достижение на "произвольном императивном коде" требует бесконечного времени в практически интересных случаях.
Во многих случаях мы даже не знаем, чему она равна. Если не верите — перечитайте Кнута:III. Банальнейшая вещь — сортировка коллекции длины L набором из N параллельно работающих компараторов. Никто не знает вид формулы для "минимального количества стадий" от L и N, и за пределами очень-очень маленьких L и N нам точно неизвестно не только, как построить оптимальную сеть компараторов, но и даже критерий, который нам скажет "эта конфигурация — точно оптимальная".
А как только мы готовы чем-то пожертвовать (например, согласиться на 99% от теоретически возможной производительности) чтобы получить реалистичные сроки проекта, то тут же на передний план выбегают декларативные конструкции и прочая высокоуровневая ерунда. Особенно с учётом того, что в большинстве практически интересных проектов в списке приоритетов корректность стоит выше быстродействия — никого не интересует супералгоритм перевода денег, который в 1% случаев закидывает не ту сумму или не на тот счёт, или просто расход с приходом иногда не совпадают.
_>Как раз наоборот. Все эти noSQL СУБД являются более низкоуровневыми, так что выжать из них максимальную производительность способен только профессионал, хорошо представляющий себе алгоритмы. В то время как SQL СУБД позволяют кому попало делать приемлемо работающие запросы, при соблюдение минимального набора правил.
Ух ты! То есть опять наши победили?
_>Ха, помнится ещё лет 5 назад прямо на этом форуме было подобное сравнение. И тогда mongo обошла sql server на каких-то рядовых (а не каких-то специальных или распределённых) запроса. Помню ещё тут были шокированные вопли типа "ну это нечестно, она же в памяти всё держит" и т.п. )))
Естественно, если решать не ту же самую задачу. Это как если бы я попросил вас разложить на множители 4096битное число, а вы мне так: "вот — 2, 2, 3! Ну и что, что получается 12 — я же справился быстрее!"
Как только мы начинаем требовать банальный ACID, да хотя бы букву D из него, все эти супер-пупер-nosql решения, а также myisam из недомускула внезапно начинают тупить глазки и говорить "ну так не честно! Быстро мы умеем делать только всякую фигню, а если вам нужны гарантии, то вы можете руками навелосипедить ACID поверх нас, и он возможно даже будет работать, и не всегда медленнее изкоробочного SQL Server Express".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[39]: В России опять напишут новый объектно-ориентированны
Здравствуйте, alex_public, Вы писали:
_>Мог бы инлайнить бесстековые сопрограммы? Что-то сомневаюсь...
Никаких бесстековых сопрограмм не существует. MSIL — это стековый язык.
_>Эмм, мы точно об одном и том же говорим? Ты считаешь, что работа с графами (дерево — это частный случай) может быть удобно реализована в рамках Linq? )))
Конечно же может. Как раз с такими вещами у Linq всё хорошо.
Но если есть какое-то недоверие к таким утверждениям, ничто не мешает написать пример задачи с графами, которая удобно реализуется в рамках "произвольного императивного кода", и посмотреть на то, как она ложится на linq.
А то может быть, мы неверно понимаем, что такое "работа с графами".
_>Разница в том, может ли этот императивный код генерироваться нашим клиентским кодом на ходу или же должен изначально загружаться админом руками.
В современных СУБД этот код может генерироваться нашим клиентским кодом на лету.
_>Ты только не путай расширения стандарта SQL (декларативного языка) в конкретной СУБД (ну например какие-нибудь конструкции типа connect by) и встроенный в большинство СУБД отдельный процедурный язык (у каждой свой).
вместо connect by в стандарте ANSI/ISO есть CTE.
В прошлый раз мы тут устраивали обсуждение задачи на графах, которая ну никак-никак не ложилась на SQL. В процессе обсуждения выяснилось, что для заданных параметров задачи, SQL Server Express выполняет "графовый" запрос, который никак-никак нельзя было сделать без кастомного middleware, за 200мс. При работе на нотубуковом процессоре и 7200rpm винте, от батарейки, со сброшенными кэшами.
И это всё — без оптимизаций, на стандартном ANSI SQL.
К сожалению, собеседник сдулся, и мы не смогли развить тему дальше — куда бы уехал SQL, если бы ему предъявили требования пожёстче. И что бы сталось с самопальным решением, если бы мы потребовали от него того же уровня ACID, что SQL сервер отдавал из коробки.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Somescout, Вы писали:
S>Там скорее (IS NOT) (NULL), а не (IS) (NOT (NULL)), по вышеописанным причинам.
Есть ещё лучше — "чему равно 'between @a'". Типа "я тут встретил странное выражение в where — 'between @a and @b'"
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Somescout, Вы писали:
V>>А по английски с NULL не сравнивают, говорят IS NULL. S>Тут же вроде не в английском дело, а в том что с NULL сравнить нельзя в терминах SQL: нельзя сравнить два отсутствующих значения.
РА и РИ (в сотый раз повторю) являются строго-типизированными.
optional<T> — вполне себе подлежит сравнению.
Т.е. вот тебе косяк конкретно SQL.
V>>Чему равно выражение (NOT NULL)? )) S>Там скорее (IS NOT) (NULL), а не (IS) (NOT (NULL)), по вышеописанным причинам.
Думаешь, этого никто не понимает? А как тогда пишут код? ))
Я как раз на этот бред и обращаю внимание, что в угоду "чтобы как в обычном языке" поломали консистентность логических операторов.
Итого, язык SQL имеет слишком много косяков. Ведь именно поэтому писать на ём большие простыни текста считается грубой инженерной ошибкой сегодня, верно? Зато сотни тыщ и мильоны строк на других языках — аж бегом.
Здравствуйте, Sinclair, Вы писали:
S>>Там скорее (IS NOT) (NULL), а не (IS) (NOT (NULL)), по вышеописанным причинам. S>Есть ещё лучше — "чему равно 'between @a'". Типа "я тут встретил странное выражение в where — 'between @a and @b'"
Действительно!
Интервал замкнут или открыт?
А как мне определить один из 4-х воможных вариантов интервала между a и b?
Re[5]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Somescout, Вы писали:
S>>Там скорее (IS NOT) (NULL), а не (IS) (NOT (NULL)), по вышеописанным причинам. S>Есть ещё лучше — "чему равно 'between @a'". Типа "я тут встретил странное выражение в where — 'between @a and @b'"
У меня ощущение что многие конструкции в SQL пришли напрямую из логики в неизменном виде: x between a and b -> x∈[a;b], exist(P(x)) -> ∃P(x) и т.п.
Здравствуйте, vdimas, Вы писали:
V>РА и РИ (в сотый раз повторю) являются строго-типизированными. V>optional<T> — вполне себе подлежит сравнению.
Можно подробнее об этом? Если мы сравниваем 5 и ничего — что из них больше? Меньше? Они равны или не равны? Во всех этих случаях ответ false. Поэтому нельзя сравнить значение поля с null — это всегда false, даже не имеет смысла сравнивать.
V>Т.е. вот тебе косяк конкретно SQL.
Не вижу косяка.
V>>>Чему равно выражение (NOT NULL)? )) S>>Там скорее (IS NOT) (NULL), а не (IS) (NOT (NULL)), по вышеописанным причинам.
V>Думаешь, этого никто не понимает? А как тогда пишут код? ))
Я отвечал на ваш вопрос, так что не знаю, как вы код пишите.
V>Я как раз на этот бред и обращаю внимание, что в угоду "чтобы как в обычном языке" поломали консистентность логических операторов.
Никто не мешает вам пользоваться консистентной NOT (x IS null). "IS NOT NULL" просто синтаксический сахар.
V>Итого, язык SQL имеет слишком много косяков. Ведь именно поэтому писать на ём большие простыни текста считается грубой инженерной ошибкой сегодня, верно? Зато сотни тыщ и мильоны строк на других языках — аж бегом.
Не соглашусь: то что вы привели не ошибки языка, это изначальный дизайн для реализации реляционной алгебры, с которой язык отлично справляется.
Другое дело, что для ORM оно не нужно в большинстве случаев — в цепочке ORM->SQL->план запроса и результат->реляционное_представление->объетное_представление средние звенья очень хотелось бы исключить более низкоуровневым языком. Если, например, смотреть на запрос, который для одной записи возвращает две связи *-to-many, то всё выглядит очень плохо: нужно либо несколько запросов делать, либо строить разреженную таблицу результатами, что никак не способствует производительности. Если бы по низкоуровневому запросу вместо реляционной таблицы с результатом возвращались бы просто сериализованные объекты — было бы проще и быстрее.
ARI ARI ARI... Arrivederci!
Re[6]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Somescout, Вы писали: S>Можно подробнее об этом? Если мы сравниваем 5 и ничего — что из них больше? Меньше? Они равны или не равны? Во всех этих случаях ответ false.
Неа. Не False.
В ANSI/ISO SQL тип "логического выражения" имеет три значения: true, false, и unknown.
Семантика where такова, что возвращаются только строчки, которые дают true. А false и unknown не возвращаются. Таблицы истинности для трёхзначной логики имеют вполне предсказуемый и интуитивно понятный вид — в частности, not unknown возвращает unknown.
Никакого отношения к "обычному языку" это не имеет. Это имеет отношение к operator lifting и математике.
Вот в C# было принято решение для boolean operators лифтинг не делать (в отличие от всех остальных операторов), поэтому там всё себя ведёт немножко по-другому. Не потому, что там не было цели приблизиться к естественному языку, а потому, что выбрали другую математику, чем в SQL.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Somescout, Вы писали: S>>Можно подробнее об этом? Если мы сравниваем 5 и ничего — что из них больше? Меньше? Они равны или не равны? Во всех этих случаях ответ false.
S>Неа. Не False. S>В ANSI/ISO SQL тип "логического выражения" имеет три значения: true, false, и unknown. S>Семантика where такова, что возвращаются только строчки, которые дают true. А false и unknown не возвращаются.
Под false я имел в виду что сравнение провалится. А результат в данном случае результат одинаков.
S>Никакого отношения к "обычному языку" это не имеет. Это имеет отношение к operator lifting и математике.
А я вроде и не сравнивал с "обычным языком".
ARI ARI ARI... Arrivederci!
Re[42]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
_>>Ну linq то тут в любом случае проиграл бы, просто из-за тормознутости сопрограмм, необходимости копирования и т.п. S>Теоретически — нет. Ничто не мешает потенциальному компилятору породить оптимальный код — наоборот, ему это сделать проще, чем в случае чисто императивного решения, т.к. намерение и механизм его реализации явно разделены. S>Я практически уверен, что если мы попробуем записать точно такой же код на cовременном C++ (с лямбдами и прочим), то результат будет неотличимым от ручного выписывания циклов for. S>Потому, что компиляторы C++ построены с применением агрессивного инлайнинга, а дальше SSA, сonstant propagation, и moving subexpression out of loop делают свою работу.
Это смотря чем ты предполагаешь заменить yield (в C++17 его пока ещё нет, т.к. как раз не смогли договориться в споре о преимуществах stackfull и stackless сопрограмм). Последние кстати как раз лоббировала MS.
S>То есть "тормознутость сопрограмм" — это ограничения JIT по инлайнингу кода. "необходимость копирования" — это как раз из-за того, что инлайнинг не случился, и нет возможности передвинуть подвыражение.
Не всё так просто. Не забывай, что бесстековая сопрограмма реализует локальные переменные под видом переменных-членов, т.е. точно как память, а не как регистры. И что бы сделать из этого аналог императивного кода (где все переменные цикла однозначно в регистрах), надо чтобы компилятор умел понимать что это периодический вызов сопрограммы и соответственно преобразовывал его.
_>>Это в любой задаче из данной области. А вот в данной конкретной задаче (где у нас вложенные коллекции и условие по предыдущему элементу) появился ещё и дополнительный алгоритмический провал. _>>Конечно. Но если ты будешь вставлять условия фильтрации грубо говоря не в блоке where, а внутри некой своей дополнительной функции, генерирующей пары, то это будет по сути уже не linq, а тот же самый императивный код. S>Нет, я не буду вставлять условия фильтрации внутри дополнительной функции. S>Я сначала натравлю на коллекцию коллекций функцию, вычисляющую атрибут, а уже потом выполню PairScan: S>
S>from pair in (from c in collectionsList select new {c, count=(from i in c where i > 2).Count()}).PairScan() where ... select ...
S>
S>Но это, по сути, беспредметный разговор. На всякий случай напомню, что код с Lag и прочим прекрасно компилируется в SQL, а его уже исполняет движок СУБД, способный радикальнейшим образом переставить порядок операций. S>Это означает, что потенциально мы можем заменить все эти примитивные версии операторов Where и Select на их ExpressionTree-аналоги, а в методы ToList и GetEnumerable() встроить полноценный компилятор, способный выполнять агрессивный инлайнинг делегатов и оптимизацию циклов. S>Более того, мы можем сделать так, чтобы вся эта адская магия срабатывала только тогда, когда у нас количество элементов в коллекции больше порогового, потому что на сотне элементов все эти вот "втрое медленнее" будут незаметны даже в микроскоп.
Ну как бы в данной подветке мы обсуждали исключительно работу с коллекциями. С СУБД и так всё понятно — там где есть Lag, имеем решение. Разве что было интересно глянуть на внутреннее устройство этой Lag (наверняка же там выбран наиболее эффективный вариант, причём не из теории).
Здравствуйте, Somescout, Вы писали:
V>>РА и РИ (в сотый раз повторю) являются строго-типизированными. V>>optional<T> — вполне себе подлежит сравнению. S>Можно подробнее об этом? Если мы сравниваем 5 и ничего — что из них больше?
Есть некий тип. Тип — это мн-во значений. Для твоего примера optional<int> Добавляет ко множеству значений int еще одно значение.
Про тип optional<T> так и говорят — это тип T+1, т.е. это тип, представляющий мн-во значений T плюс еще одно специальное значение, которое имеет семантику "нет значения" для логики программы (то бишь для программиста).
Но с т.з. типа T+1 — это вполне себе валидное значение.
Дальше продолжать?
S>Меньше?
Можно оределить и оператор < для области опеделения T+1, если хочется.
S>Они равны или не равны? Во всех этих случаях ответ false. Поэтому нельзя сравнить значение поля с null — это всегда false, даже не имеет смысла сравнивать.
Имеет, имеет.
К тому же, тривиально реализуемо.
V>>Итого, язык SQL имеет слишком много косяков. Ведь именно поэтому писать на ём большие простыни текста считается грубой инженерной ошибкой сегодня, верно? Зато сотни тыщ и мильоны строк на других языках — аж бегом. S>Не соглашусь: то что вы привели не ошибки языка, это изначальный дизайн для реализации реляционной алгебры
Нет в SQL никакой реляционной алгебры. Есть бестиповое реляционное исчисление в исходнике.
Бестиповое — потому что сам язык имеет скриптовую природу, т.е. типизация тут сугубо динамическая.
И вся эта тема аккурат про попытки убежать от динамической типизации.
S>с которой язык отлично справляется.
Ну да, почти все скриптовые языки всегда "отлично справляются".
Но большие простыни кода на них писать не рекомендуется.
S>Другое дело, что для ORM оно не нужно в большинстве случаев — в цепочке ORM->SQL->план запроса и результат->реляционное_представление->объетное_представление средние звенья очень хотелось бы исключить более низкоуровневым языком. Если, например, смотреть на запрос, который для одной записи возвращает две связи *-to-many, то всё выглядит очень плохо: нужно либо несколько запросов делать, либо строить разреженную таблицу результатами, что никак не способствует производительности. Если бы по низкоуровневому запросу вместо реляционной таблицы с результатом возвращались бы просто сериализованные объекты — было бы проще и быстрее.
Возвращались бы типизированные записи, т.е. байты, которые заранее известно как реинтерпретировать, т.е. без динамического маппинга из некоего Recordset с проверкой типа каждого значения каждого поля из каждой строки, верно?
Дык, об этом и речь.