Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, samius, Вы писали:
S>>Что всё? Дотнет нейтив? Ну будет на худой конец компилятор указывать тип компарера.
V>Не будет до тех пор, пока ограничения генериков не станут частью типа.
Что мешает?
V>>>>>Это отказ от обсуждения систем типов и возможностей параметрического полиморфизма? ))
S>>>>List<T> параметрически полиморфен. Что тут еще обсуждать?
V>>>Обсуждалась система типов + курьёзы, связанные с т.н. "типизированным параметрическим полиморфизмом", при попытке использовать его в стиле тру-ООП, когда разработчики такой системы типов решают облегчить себе жизнь.
V>>>Не работает это...
S>>Твой курьез не сработал. Я написал IndexOf извне класса и система типов пережила это.
V>Да ничего ты не написал. ))
V>У тебя нет самой возможности писать конкурирующие специализации в C#, типа таких:
Так ты хотел именно конкурирующие специализации? Извини, из твоих постов я это не понял. А к чему они нужны, что они доказывают?
V>V>class MyExtentions
V>{
V> public int IndexOf<T>(IList<T> list, T value) {}
V> public int IndexOf<T>(IList<T> list, T value) where T : IEquatable<T> {}
V>}
V>
V>В С++ такой трюк возможен, в Хаскеле возможен, в C# — нет.
Верно, нет. Но если бы было возможно, это был бы ad-hoc. Так к чему это все?
V>>>В общем, я тут больше отвечал тем, кто считает, что в С++ обитает "неполноценный параметрический полиморфизм".
S>>Конечно обитает. И полноценный параметрический там тоже обитает.
V>Тут просто надо помнить, в чем был аргумент этих горе-обвинителей. По их мнению, "полноценный" — это который работает на рекурсивно-определяемых типах. Правда, эти обвинители не обратили внимание, что ограничение на рекурсивно-определяемые типы в С/С++ никак не связаны с параметрическим полиморфизмом, что последний унаследовал исходные возможности объявления типов языка.
Вот зачем ты мне рассказываешь про каких-то горе-обвинителей? Они не смогли оценить твою победу над ними и ты хочешь что бы я сделал это за них? Их аргументов я не видел, отвечать за них не буду. Разделить твою победу тоже не могу.
V>>>Там, где ты рядом скипнул, содержалась полная инфа относительно вида параметрического полиморфизма в С++ (он имеет вполне определённую классификацию — т.н. "нетипизированный параметрический полиморфизм"), а так же объяснял, как легко и непринуждённо из нетипизированного сделать типизированный, причем, более полноценный, чем "тру параметрический полиморфизм" в дотнете.
S>>С IEquatable ты там кучу кода написал, но од ad-hoc не ушел и к чистому параметрическому не пришел.
V>Так я там и показал совместную работу двух видов полиморфизма — я продемонстрировал, как породить специализацию для ограниченного семейства типов из изначально неограниченного. А чтобы было понятней — я сделал это ограничение аккурат на манер дотнета, а именно — указал в кач-ве ограничения базовый класс.
Дотнет тоже умеет использовать ad-hoc.
V>Так-то в С++ можно придумать овердохрена способов всевозможнейших ограничений.
V>См. type traits и function traits.
Ну можно.
V>>>Нужна, но это невозможно для ситуации, если речь идёт об автоматически подставляемом компилятором генерик-компараторе. Тут даже не важно, value-type или ref будет этот компаратор. Соответствующий сниппет я уже приводил. Не компиллируется.
S>>Он не компилируется лишь от того, что ты вкорячил его в List<T>, которому не захотел ограничивать T.
V>Я не "не захотел". Я не смог.
V>И ты не сможешь.
V>Потому что нельзя породить несколько версий List<T> с разными ограничениями на T. Или в одном List<T> нельзя давать методы с разными ограничениями на T.
А ЗАЧЕМ?
S>>Если вынести — все компилируется. Но это все равно ad-hoc.
V>Курьёз в том и состоит, что как пример ad hoc-полиморфизма ты мне приводил в Хаскеле как раз те примеры, где ограничение на тип является частью полиморфного типа.
Какая разница? elem — ad hoc. IndexOf — ad hoc. Что именно меняет то, на что ты упираешь?
V>Т.е., курьёз у тебя происходит классический: тут смотрим, тут не смотрим, тут рыбу заворачиваем. ))
И там и там смотрим — видим ad-hoc. Рыба у тебя какая-то с параметрическим elem.
V>В Хаскеле для ad hoc полиморфизма тебе потребовалось ограничение внести в систему типов, в C# уже не требуется, "это всё равно ad-hoc".
V>Сорри, детсад.
Детсад — это утверждение что система типов каким-то образом влияет на то, ad hoc или нет. Покажи, откуда это вообще следует?
V>В случае обеих языков ad hoc происходит не там.
нене, языки тут не при чем. Это в твоей голове ad hoc происходит не там.
V>>>Это не мне. Это системе типов дотнета.
V>>>В Хаскель и С++ запросто сделать отдельные специализации для IEquatable<> и для любых других мыслимых "концептов".
S>>Специализации! слово-то какое. Прям — ad-hoc.
V>Верно.
V>Просто не надо путать "специализацию" и "ad-hoc полиморфизм".
Как раз надо. Специальное знание о типе — и есть ключевое отличие от параметрического, где это знание не требуется.
V>Я сразу же тебе и сказал, что ad-hoc полиморфизм достигается через специализацию.
Разве ж я с этим спорил?
V>Но не обязательно через специализацию достигается сам полиморфизм. Чаще всего (уже обращал твоё внимание) специализация нам нужна для типизации "черного ящика" до "концепта". Что такое "концепт" тоже говорил уже — это такой "черный ящик", для которого дан набор операций.
Вот набор операций — это уже специализация. Параметрический полиморфизм не требует набора операций.
V>>>Речь сугубо о выразительности библиотек, об отсутствиии необходимости плодить ручную работу (клонирование) — рядом приводил уже ссылки на автогенерённый код, повторить ссылки? В общем, с учётом обсуждения рядом Net Native и ограничений на рефлексию — вопрос не праздный.
S>>Да уперся ты в рефлексию!
V>Я привел её как пример дурных следствий из недоработанной системы типов дотнета.
V>Если бы были допустимы конкурирующие определения для IndexOf, данные мною выше в этом же посте, то никакая рефлексия была бы не нужна.
V>Хаскель же как-то работает без рефлексии?
Ну пусть система типов дотнета недоработана. Я с этим не спорю. Я лишь утверждаю что это не имеет отношения к ad hoc/параметричности полиморфизма.
V>>>Кодогенерацию через T4? ))
S>>Тоже не повлияет на классификацию
V>Ну я-то не на классификацию пытаюсь повлиять, а на тебя. ))
V>Потому что так смешно вышло, что в дотнете отсутствуют те ср-ва, которые ты назвал необходимыми и достаточными для ad hoc полиморфизма в Хаскеле. Неужели в дотнете нет ad hoc полиморфизма? ))
Жжошь напалмом! Есть в дотнете. Перегрузка операторов и функций, приведение типа, переопределение виртуальных методов, ограничения дженериков. И это все ad hoc. Аналогом хаскелевский классов типа я считаю ограничения дженериков. Кстати, обращу твое внимание, Хаскель появился двадцать с лишним лет спустя после введения классификации Стрэчи. По-твоему до этого не было языков с ad hoc полиморфизмом?
V>Или неужели ты не видишь, к чему я давно клоню — что раз в дотнете есть ДРУГИЕ ср-ва для организации ad hoc полиморфизма, чем упомянутый трюк в Хаскель-вики, так может, признаком ad hoc является что-то другое?
Конечно, является. Как ты догадался? В вики прочитал?
V>>>Тогда можно было бы использовать т.н. "специализацию" (ad hoc), чтобы иметь возможность автоматически распространять ограничения текущего контекста вычислений для низлежащего вызываемого кода.
S>>Напиши код, плиз. Только подробно, чего ты хочешь добиться, и почему это не получается.
V>Одного объявления мало, что ле?
V>Ну вот с телами:
V>V>static class MyExtentions
V>{
V> static public int IndexOf<T>(this IList<T> list, T value)
V> {
V> for (int i = 0; i < list.Count; i++)
V> if (Object.Equals(list[i], value))
V> return i;
V> return -1;
V> }
V> static public int IndexOf<T>(this IList<T> list, T value) where T : IEquatable<T>
V> {
V> for (int i = 0; i < list.Count; i++)
V> if (list[i].Equals(value))
V> return i;
V> return -1;
V> }
V>}
V>
V>И вот никакая динамическая диспетчеризация через абстрактный компарер уже не требуется для большинства сценариев.
V>А значит, не требуется и кодогенерация через T4 под эти сценарии.
Все стало только хуже.
Итак, предположим что это работало бы в дотнете. (я вообще не против такой возможности, я просто не понимаю, какое отношение она в твоей голове имеет к ad-hoc). Одна диспетчеризация производится компилятором в момент проверки наличия ограничения для конкретного T. Уже диспетчеризация и уже использование специального знания о T. Уже ad-hoc как с выбором оверлоад метода. Далее, в первом методе идет вызов Object.Equals, который обращается к виртуальному методу Equals. Еще одна диспетчеризация, но уже времени выполнения. Второй метод с ограничением указывает на то, что для значения типа T определен СПЕЦИАЛЬНЫЙ код для выполнения сравнения. Тут ad-hoc полиморфны все варианты без вариантов.
V>>>Сейчас же в дотнете НЕТ никакой возможности распространить такие ограничения дальше.
V>>>И не надо защищать систему типов C# только за то, что это C#. Будь объективен.
S>>Я не защищаю (пока). Я просто понять пока не могу, что не так с IndexOf, который вне списка.
V>А какая разница, внутри или вне?
Я же тебе об этом и говорю.
V>Если сделать как показал выше, то получим ошибку:
V>V>error CS0111: Type 'MyExtentions1' already defines a member called 'IndexOf' with the same parameter types
Так убери конкурирующую специализацию или переобзови ее другим именем. Получишь 2 метода, у которых ad-hoc полиморфизм, но хоть они будут компилироваться и работать.
V>Если разнести эти определения по разным MyExtentions1 и MyExtentions2 и потом попытаться использовать ad-hoc полиморфизм на IndexOf:
Ты не можешь его попытаться использовать. Ты можешь его попытаться не использовать, но от ad-hoc ты никак не отделаешься. IndexOf обречен, т.к. сравнивает экземпляры/значения. Все что сравнивает — делает это специальным образом для каждого типа. И любой тип, который ты подашь в IndexOf, будет требовать специального сравнения, а значит, специального кода для типа T. Не говоря об ReferehceEquals. И вот уже то, что для разных типов по-разному — уже указывает на ad hoc.
V>>>Речь идёт вот о такой предполагаемой фишке:
V>>>V>>>class List<T> : IList<T>
V>>>{...}
V>>>class List<T> : IList<T> where T : IEquatable<T>
V>>>{...}
V>>>
V>>>Разные типы. Пример совместной работы ad hoc и параметрического полиморфизма (рядом ты тоже малость путал одно с другим).
S>>Нету тут совместной работы. Потрял квантор всеобщности у T => нет параметрического полиморфизма.
V>Нет, не потерял. Параметрический полиморфизм НЕ требует работы ф-ии на ЛЮБЫХ входящих типах. Достаточно работы на более одном типе.
ЧТО??? По-твоему любая мономорфная функция параметрически полиморфна?
S>>То что получилось — специализация через ограничения. А это ad-hoc.
V>Тем не менее, методы каждой из версий класса List<T> параметрически полиморфны прямо по-определению параметрического полиморфизма.
Это не так. И даже для невыдуманного List<T>. BinarySearch, Contains, IndexOf, LastIndexOf — ad hoc.
V>Итого — совместная работа.
На разных наборах методов.
V>>>Или вот о такой:
V>>>V>>>class List<T> : IList<T>
V>>>{
V>>> public IndexOf(T value) {}
V>>> public IndexOf(T value) where T : IEquatable<T> {}
V>>>}
V>>>
V>>>Разные методы, опять совместная работа разных видов полиморфизма.
S>>Вынеси метод и все будет.
V>Вынес. Ничего не было.
Так тебе же все сразу...
S>>В Хаскеле список не тащит ограничений на тип элемента.
V>Я показал рядом пример с методами-расширениями в C#. Не компилируется.
Только потому что тебе нужна перегрузка и с ограничением и без одновременно. Естественно. Но это ничего не меняет в отношении ad hoc.
V>>>Обрати внимание, что в дотнете последняя техника особо мощно смотрелась бы в сочетании с техникой методов-расширений. Это была бы просто киллер-фича, натурально.
S>>Я тебе предложил метод расширение IndexOf, но не пойму, что ты от него нос воротишь.
V>До тех пор, пока не компилируется, имею право, как бэ. ))
Право имеешь.
V>>>А то сейчас на код методов-расширений порой без слёз не взглянешь, когда они пытаются через рефлексию отделить массив от List<T> и от IEnumarable<T>. Согласен, порой и такое полезно, когда произошло стирание типа аж до IEnumerable<>, но уж в случае более полных специализаций можно было бы подставлять совсем эффективный код.
S>>Не понял, где там рефлексия в отделении массива от IEnumerable<T>.
V>В реализации системных библиотек Linq.
V>Происходит рантайм-проверка типа аргумента и ветвление алгоритма.
Ах, вот что ты называешь рефлексией? Ну делалось бы это через visitor... Что бы изменилось? Один хрен ad hoc. (ой, чувствую, щас начнется)
V>Будь внимательней, я говорил о всяких классификациях внутри 1-го ранга одного лишь параметрического полиморфизма.
V>А плане ad hoc полиморфизма разногласий обычно нет.
V>Ты первый. )))
После хаскельвики и просто вики?
V>>>В дотнете ограничения на тип НЕ являются частью типа. Ну вот попытайся ты хаскелистам объяснить, как так у вас вышло, что параметрические аргументы методов или типов навроде `Eq a` и `Num a` с т.з. системы типов неразличимы.
V>>>Услышишь много интересного.
S>>не распарсил
V>А зря. По всей этой ветке это был тот самый единственный, который необходимый и достаточный аргумент, дающий исчерпывающий мой поинт относительно проблем параметрического полиморфизма в C#.
Мы пока еще не договорились по поводу того, что считать параметрическим. Ты привел примеры ad hoc. И в C# они тоже ad hoc.
V>ОК, вот точный аналог упомянутого в дотнете:
V>V>static class MyModule
V>{
V> static public T Foo<T>(T value) where T : Eq<T> {}
V> static public T Foo<T>(T value) where T : Num<T> {}
V>}
V>
V>В дотнете такое не компиллируется.
V>А в Хаскеле подобный сценарий — это основа основ современных практик для этого языка.
Пусть, но это ad hoc. И если бы скомиплилось в дотнете, все равно им бы оставалось.
V>>>Просто нашел собеседника, которому можно подобное озвучивать и он достоверно поймёт, о чем речь. ))
S>>Ошибся, походу.
V>Да уж...
Точно.