Re[16]: В России опять напишут новый объектно-ориентированны
От: vdimas Россия  
Дата: 02.03.18 14:24
Оценка:
Здравствуйте, Sinclair, Вы писали:

V>>Это ограничения языков, где "класс" — это что-то занимающее место в релизе.

V>>В компиллируемых языках типы стираются.
S>Дело не в бинарнике, а в объёме рукопашного кода. Если мне надо каждый select предварять отдельной декларацией public class StudentFirstAndLastName, то я умру это делать, и откажусь от проекций совсем. В классических ORM-приложениях так и делают — там принято не задумываться о том, что мы протаскиваем через игольное ушко лишние мегабайты.

Абсолютно согласен.
Поэтому я и позволил себе говорить о другом языке, заточенном на все эти сценарии с данными.
Проекция — это ж наипервейшая операция порождения типов кортежей "по-месту".
Т.е. можно повторять бесконечно — РА и РИ строго типизированы в своей сути.


S>В Linq ситуация чуть-чуть получше, с возможностью локально использовать анонимные классы.


Тоже верно. Но мне, как разработчику, хочется сделать этот автовыводимый тип как public. Более того, я еще хочу иметь возможность присвоить этому типу имя.
(Тут ты уже начинаешь быть конструктивным — проводишь анализ и выходишь на некие пункты из большого списка требований)

И я не хочу слишком странного, заметь. ))
Например, в современном С++ такое возможно через комбинацию auto, typedef и decltype.
Но даже такая связка недостаточно удобна, как по мне, т.к. декларация typedef — она независимая от целевого метода, возвращающего "анонимный" тип, а хочется именно привязать одно к другому.


S>Но этого всё равно недостаточно для того, чтобы писать по-настоящему универсальный повторно используемый код.


Да. "Мелочей" хватает, стоит только копнуть. О чём и речь.
Примеры можно приводить бесконечно.
Например, взять автовычисляемые поля.
Если "исходники" данных для вычисляемого поля так же идут по сети в рамках того же экземпляра кортежа, то значения автовычисленных полей, передаваемых по сетке, будут избыточными. В общем, когда некая "одна система" будет ответственна за оба конца транспорта, то она может использовать знания о происходящем для оптимизаций ф-ии доставки данных.


S>Потому что я не могу написать, к примеру, функцию, которая принимает на вход "IQueryable, параметризованный любым типом с FirstName и LastName", и возвращающую "IQueryable, параметризованный типом с теми же свойствами, что и у аргумента, плюс string FullName".


На шаблонах С++ можно. В любом случае в момент компиляции всё разресолвится.
И как раз под это дело разрабатывают концепты.
Концепты можно наложить сверху, чтобы исключить, скажем, банальные описки.
Вдруг ты опишешься в исходнике шаблона и у тебя наряду с FullName будет обращение к полю FullNam, и ни дай бог в подаваемом типе кортежа будет поле FullNam — в этом случае даже компилятор не поможет. Такие сценарии были замечены в плюсах давно, поэтому и вышли на необходимость концептов, которые активно разрабатываются для одной из следующих версий языка.

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

Для нынешней динамики SQL это всё недостижимо, ес-но. О проблемах узнаешь только в рантайм и то, зачастую когда уже поздно. ))


S>Хотя уже можно делать штуки типа

S>IQueryable<T> FilterByDateRange(this IQueryable<T> input, Expression<Func<T, DateTimeOffsetDate>> dateSelector DateTimeOffset? from, DateTimeOffset? to)

Но выглядит страшно, согласись. ))


S>И не велосипедить однообразные ветки if в "прикладных" функциях:


C# вообще плохой пример — его параметрический полиморфизм неполноценен.
Ограничения типов (которые на сейчас сейчас даются в виде интерфейсов и базовых классов) должны составлять полную сигнатуру типов и их членов, но эти ограничения не входят в сигнатуру типа и его мемберов.

В С++ тоже не входят, но трюк с частичной специализацией позволяет разруливать аналогичные сценарии хотя бы для типов. Но для методов напрямую разрулить невозможно, тоже косяк. Поэтому применяют следующую технику:
метод<T1, T2, ..>(T1 arg1, T2 arg2, ...) { вспомогательный_тип_диспетчер<T1, T2, ..>::целевой_код(arg1, arg2, ...); }.

И это я не в кач-ве ликбеза даю а лишь с целью демонстрации того, что определённые знания по проблематике существующих языков есть, т.е. есть довольно внушительный список пожеланий к языкам, что именно от них надо, чтобы не извращаться в коде как показывал ты или я.
Отредактировано 02.03.2018 14:29 vdimas . Предыдущая версия . Еще …
Отредактировано 02.03.2018 14:28 vdimas . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.