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