Re[3]: Важны ли мелочи в ЯП?
От: vdimas Россия  
Дата: 05.01.25 21:29
Оценка: 2 (1) +1
Здравствуйте, Sharov, Вы писали:

V>>С лямбдами там раз в 10 лучше, чем в C#.

V>>Они не сделали ошибки типизации делегатов, там функциональный тип вполне честный, как в JS, поэтому всё нааамного проще/интероперабельней.
S>А что не так с типизацией делегатов в C#?

1. Делегаты разных типов не совместимы, даже если совместимы их сигнатуры. "Приведение совместимых сигнатур" на деле означает создание нового делегата, который вызывает метод Invoke у целевого.

2. Само создание делегатов очень затратное — примерно в 3-5 раз дороже создания обычного объекта. Без привязки к специфическому типу и без инициализации доп.полей, служащих исключительно и только целям рефлексии, без генерации тела Invoke на лету (оно разное для экземплярных и статических методов) создание делегата было бы не дороже создания обычного объекта, как оно есть в остальных языках, поддерживающих функциональный тип.

Например, в статически-типизированных языках все thunk-и созданы заранее для всех мест, где создаются лямбды. В дотнете, однако, даже для статически-типизированных мест вызывается тот же код инициализации делегата, что и при создании делегата динамически из хендла-метаинформации метода. И это настолько забористая дичь, однако, что нема словей, одни выражовывания.

Одним словом, изначальное качество проектирования платформы ни к чёрту.
Местами такое ощущение, что самоучки от IT ваяли. ))
А теперь уже хрен переиграешь.

3. Библиотечные костыли, навроде Action<> и Func<>, призванные исправить недостаток п.1. хотя бы в самых общих местах нового кода (старый остался смердеть навечно из-за требований совместимости с г-ном 22-хлетней давности), в любом случае не покрывают in/ref/out-спецификации аргументов. В этом месте надо описывать уникальные делегаты, привет п.1.


=====================
В своём коде накатал struct-based библиотеку функциональных объектов с полагающимся минимальным джентльменским набором биндинга, реордеринга, apply и прочего.
Удалось единообразно покрыть как старые делегаты, так и новые unmanaged-делегаты, то бишь простые указатели на ф-ии, которые работают со скоростью света — примерно как в С/С++, т.е. ничего не стоят при создании и почти ничего не стоят при вызове. Ну и свои легковесные struct-based и class-based функторы на манер C++, разумеется. Жаль, пока не удалось допилить внутренние кишки async-автоматов, генерируемые компилятором (т.е., встроиться туда для своих Task-like объектов удалось легко, но заставить генерить код автомата без использования делегатов — пока нет, руки не дошли... и пока что асинхронщина дотнета — это та еще гиря на ногах, еле пыхтит, бедненькая... )) )

И да, в 64-битных ABI вызовы экземплярных и статических методов одинаковы, этим хаком можно с должной аккуратностью пользоваться на 64-битных платформах, т.е. покрывать указателями на мемберы не только статические методы, но и экземплярные.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.