Re[12]: IEquatable<T>
От: samius Япония http://sams-tricks.blogspot.com
Дата: 14.02.17 05:26
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, samius, Вы писали:


V>>>Я не прав был, что не изучил её (простыню) всю? ))

S>>Сам же и ответил. Не поняв, ЗАЧЕМ, изучил всю, вынес вердикт не о том, о чем была дана ссылка и контекст.

V>Потому что это было уныло — расписывать.

V>Я хорошо понял зачем.
V>Унылость была в том, что коллега не расписал свой аргумент, т.е. отвечать было не нечего, а не на что. Начался отрезок бессмыслицы в обсуждении.

V>Я его просто ткнул носом в слабость его аргумента и удивился потом с того, что коллега даже не понял, во что именно я его ткнул. ))

V>И еще показал, что я подобных флуктуаций его сознания уже ожидал:
V>http://www.rsdn.org/forum/flame.comp/6662410.1

V>Там действительно, лишь флуктуация.

V>Т.е. человек помнит "трюк" насчет ограничений генерик-аргументов, но не помнит, куда и как его можно применять.
Я вот поглядел твои примеры, и у меня ровно такое же впечатление о тебе.
Да, извини что я не на каждую твою фразу отвечаю, уж слишком много!


V>>>Вместо такого фокуса коллега мог назвать конкретный метод конкретного типа и никаких ссылок не надо — кому попервой и даже любопытно, пусть смотрит сам. А остальным, кто еще 12-15 лет назад это всё уже прожевал и выкакал, сорри, тому банально не любопытно глазеть на подобный код.

S>>Коллега понадеялся что контекста обсуждения было достаточно. А в отношении любопытства остальных — согласен. Возможность — юслес на 99% (ИМХО).

V>Коллега не умеет формулировать свои мысли. Если бы он попытался формально расписать свой аргумент, то САМ увидел бы, что его аргумент НЕ канает. Бо в хорошем вопросе содержится половина ответа. И тут как раз тот случай.


V>Сам разве не обратил внимания, что между List<T> и ограничением IEquatable<T> нет никакой связи на уровне типов языка.

А ты не обратил внимания, что между списком в Хаскеле и Eq a тоже нет никакой связи на уровне типов языка?
V>Он ведь правильно пишет (по наитию, скорее):
V>

V>Как он (comparer) там создаётся вообще пофигу.

V>"Пофигу", потому что ему хочется проигнорить вот этот "разрыв" в системе типов, из-за чего, собсно, и подключается рефлексия.
Какая рефлексия в List<T>?

V>Но оно не пофигу, коль он взялся опровергать вот это:

V>

V>Собсно, вообще таких алгоритмов мало, которые можно выразить в дотнете для value и ref-типов в генериках и они будут корректно работать в обоих случаях.

V>Потому что из-за отсутствия связи на уровне типов в этом месте НЕЛЬЗЯ подать value-type GenericEqualityComparer<T> where T : IEquatable<T>, даже если бы сигнатура метода была примерно такая:
V>
V>class List<T> {
V> public int IndexOf<TComparer>(T value, Comparer comparer) where TComparer : IEqualityComparer<T> {...}
V>...
V>}
V>

V>Т.е. в этом месте можно было бы подать лишь НЕ генерик-реализацию в случае value-type компаратора, т.е. его аргумент аннигилируется без моей помощи. ))
Тебе принципиально впендюривать IndexOf с генериккомпарером внутрь List<T>?

    static class MyExtensions
    {
        public static int IndexOf<T, TComparer>(this IEnumerable<T> source, TComparer comparer)
            where T : IEquatable<T>
            where TComparer : IEqualityComparer<T>
        {
            throw new NotImplementedException();
        }
    }



V>Потому что требуемое ограничение надо было бы распространить выше:

V>
V>class List<T> where T : IEquatable<T>
V>

V>что являлось бы суровым ограничением.
Тут согласен с тем что "являлось бы", но не согласен, что "надо было бы".

V>* Мне приводят пример, где GenericEqualityComparer<T> создаётся через рефлексию, потому что система типов не позволяет указать его явно в исходнике.

Какая разница, как он создается, если он закэширован?

V>* В целевом алгоритме НЕТ никакого трюка по вызову методов целевого типа T.

Указывай ограничение — будет трюк.

V>* Все операции делаются через т.н. "словарь операций", где сам словарь НЕ обязан быть генерик-словарём, там используется обычный ООП-интерфейс.

Я не вижу в этом существенного недостатка.

V>Что в случае специализации в рантайме конкретным value-типом, отличным от Nullable<T2>, например, простым int (не суть важно, просто пример конкретного типа) даст вот такой код:

V>
V>    public override bool Equals(int x, int y)
V>    {
V>       return x.Equals(y);
V>    }
V>


V>Вот ЭТО и есть пример "алгоритма"?

Ну, знаешь. Это пример. А еще у меня году в 2005-м была триангуляция с этим трюком. Исходники не проси, код закрыт режимом.

V>===================

V>Я бы мог всё это дать сразу, но тут сработал такой момент, что когда собеседник "претендует" на некий уровень (а сходу взятый надменно-язвительный тон и регулярное переименование заголовков сообщений в некие "намеки" означает именно это, верно?), то сей "уровень" надо ж уметь поддерживать, не? ))
Т.е. ты не дал, хотя мог, а собеседник должен был дать?

V>В общем, я не должен был всю эту банальщину тут расписывать. Ведь со стороны дотнета выступал не я. А то получается, что я должен был начать сам с собой спорить, бо оппонент за себя не тянет.

Или не хочет.

S>>80% технологий еще древнее. Если не больше.


V>Верно. Поэтому совсем уж заходить на банальности, а тем паче начинать плавать по ним — это банально моветон.

V>Тем более, плавать со "своей стороны баррикад". ))
А с противоположной стороны можно плавать?

V>>>1. там в любом случае происходит вызов метода интерфейса;

S>>Вероятно, но вызов метода интерфейса не через интерфейс там тоже происходит.

V>И ты, Брут?

V>Нет, не происходит.
Так как по-твоему вызываются методы IEquatable<T>?

V>С точки зрения метода IndexOf, мы вызываем методы "черного ящика" — поданного извне словаря операций. Вызовы метода по ограничениям — это уже подробности реализации этого черного ящика и никак не связаны с целевым алгоритмом. Более того, уже показал выше, почему этот "черный ящик" не может иметь генерик-реализацию value-type в системе типов, т.е. у нас тут получаются ДВА независимых разных алгоритма, работающих совместно.

То что ты показал выше — неубедительно. Я не понял, почему не может.

V>Т.е., мы заведомо имеем дело с "нетипизированным параметрическим полиморфизмом".

V>Подробно я описывал тут: http://www.rsdn.org/forum/flame.comp/6680620.1
А куда делся IEquatable<T>? Он ведь обеспечивает типизированность.

V>Блин, ну вот целиком пример (заставляете тратить время на запуск Студии, бо я уже и сам начинаю сомневаться, ы-ы-ы):

V>
V>    class MyList<T>
V>    {
V>        public int IndexOf<TComparer>(T value, TComparer comparer) where TComparer : IEqualityComparer<T>
V>        {
V>            return 0; // заглушка
V>        }

V>        // Не компиллируется! 
V>        public int IndexOf<TComparer>(T value)
V>        {
V>            return IndexOf(value, new GenericEqualityComparer<T>());
V>        }
V>    }
V>

V>А не, всё верно, не компиллируется нифига.
Ты ведь выше сам написал, что нужно добавить ограничение на MyList<T>. Но это если тебе надо IndexOf иметь именно в нем. Нафига — не понятно.

V>Кароч.

V>Именно из-за нетипизированной природы параметрического полиморфизма в предлагаемом МНЕ примере-аргументе мы НЕ МОЖЕМ вызывать методы типа T в теле методов MyList<T>.
А надо вообще?

V>Ву а ля? Или еще нет?

Да как-то мимо и не по делу. Вот в Хаскеле тоже elem никто не пихал в список. И в std::vector нет ничего подобного. Но в C# тебе надо обязательно indexof засунуть в коллекцию, которая не предполагает сравнения элементов. Или ты решил повторить ошибки дизайна коллекции версии 1 и 2?

V>Но фиг с ним, это всё банальности и я в шоке, что их потребовалось расписать настолько подробно на 15-й год существования дотнета. Дело не только в этом. Различная null-default(T) семантика value и ref типов накладывает свои дополнительные ограничения и тоже резко сужает класс алгоритмов, которые можно было бы выразить прямо из Т, без прибегания к технике "словарей операций", которые, цитирую сам себя:

V>

V>... в концепции дотнетного ООП такая техника выглядит заимствованием из чужеродного ФП.

V>Т.е., те фишки ФП, которые не руинят ООП — они в практику дотнета таскаются с удовольствием, смотрю. Остальные практики игнорятся, хотя именно такая реализация параметрического полиморфизма требует именно таких практик.

V>И я имел ввиду больше вот эти ограничения на разницу в семантике (в одном случае идёт прямая адресация, в другом косвенная), которые не всегда просто преодолеть — оформить непосредственно в виде генерик-кода БЕЗ прибегания к посторонним "словарям операций". Каждый такой словарь — это костыль. В С++ можно обойтись без него, в этом была суть уже моего аргумента. Хотя, можно и с таким же точно костылём — но в С++ хоть есть выбор.
В C# тоже есть выбор. Не надо мучить мягкое место через передачу дженерик словарей операций. Интерфейсов достаточно в подавляющем большинстве случаев. Ну а если ты решил сделать Bitmap<T> размером 4KK и хочешь применять на нем свертку с частотой 60Hz, то ты выбрал не тот инструмент.

V>>>2. дефолтный компаратор порождается через рефлексию; особенно весело сие после пространных рассуждений коллеги о "безопасной компиляции";

S>>Как создается дефолтный компарер — не имеет отношения. Тем более, что он кэшируется.

V>Т.е., таки, Брут. ))

V>Имеет в том плане, что может быть создан ТОЛЬКО через рефлексию.
м? А new MyGenericComparer<T>() кто запретил? Тем более, если ты его собрался передавать по значению...
V>Кеширован или нет — отмазки, это же просто некое инженерное решение-следствие, т.е. уже не принципиально в этом споре.
V>Более того, само наличие отдельного компаратора, даже для случая встроенных типов — это ой. Потому что в теле самого List<> мы беспомощны.
Далось тебе его тело.

S>>а методы IEquatable<T> каким образом вызываются? О них ведь речь была.


V>Методы IEquatable<T> в целевом алгоритме не вызываются никак, даже после Джитта, увы. Вызываются методы черного ящика, причем, исключительно как виртуальные. Т.е., что там на "другой стороне" уже не принципиально.

По-твоему там еще и боксинг? Это не соответствует действительности.

V>Т.е., в обсуждаемом примере через "водораздел" ООП-полиморфизма происходит выход на ad hoc полиморфизм. А вот последний может, в свою очередь, может быть реализован и через параметрический полиморфизм и через что угодно. Одно плохо — в системе типов языка последнее невыразимо вообще никак.

Ad hoc через параметрический? Ты бы показал Wadler-у, а то он классы типов вводил, бедолага.


S>>Я полагаю что вы говорили о чем-то разном, подразумевая что об одном и том же.


V>Я полагаю, что коллега плохо понимает, о чем речь, но обвиняет в плохом понимании окружающих.

V>Причем, ответвление на vector<> показало вообще кошмар в плане дедуктивных способностей и навыков ведения спора / аргументирования.

V>Вот тут примерно так же — вместо обсуждения сабжа коллега радостно зацепился за мою фразу "вызов Equals у базового Object", хотя к сути происходящего в методах List<T> оно вообще не имело никакого отношения. Даже само это цепляние было самоподставой (чел повелся на троллинг), ведь в системе типов языка нам доступна только реализация указанного мною ObjectEqualityComparer и я недвусмысленно на это намекал.

V>Похоже, ты тоже не понял тот "тонкий" троллинг с моей стороны... Но ты-то ладно, это было обсуждение не с тобой, ты не обязан вдумываться в чужие споры.
В обсуждении со мной я тоже твой "тонкий" троллинг не понимаю.

V>Кароч, это я уже сам себя веселил, видя полнейшую слепоту оппонента колеги Qbit86.

V>Просто троллинг был уже нифига не тонкий, вот в чем был самый юмор ситуации, как по мне.

V>Но все-равно коллега так и не увидел, в чем там собака зарыта... Ну и фиг с ним, значит и не хотел...

V>Но потом заканчивает своё непонимание рассуждениями о том, что я даже на джуниора не тяну.
V>Блин, куда катится мир?

V>На Украине пещерные люди отодвинули грамотных. На форуме тоже порой просто засилье, скажем так, глубоко несообразительных людей... что ваще происходит-то??? )))

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

V>>>Хотя, если упустить весь рисунок развития ситуации, согласен, моя реакция может показаться странной. Там надо на десяток постов вверх подниматься и смотреть на картинку целиком.

S>>Смотрел вчера, картина не стоит того.

V>Я уже высказывал своё восхищение твоими манерами, но нет.


V>Понимаешь, дело вовсе не в том, что коллега чего-то не понимает.

V>Невладение какой-то инфой здесь и сейчас — оно ведь совершенно не страшно.
V>Я бы даже сказал — это полная ерунда, не принципиально ни разу.
V>Страшно, другое — когда и не хотят владеть.
Тут согласен. Но не могу согласиться что это про Qbit86.

V>Еще более страшно, когда оппонент сходу переходит к мелким гадостям — подколкам, язвительности, троллингу и т.д. и т.п. на ровном (на тот момент) месте. С чего бы это, ы?

Да там еще разобраться бы, кто вперед перешел.

V>Вот такие мелкие подлости, да еще от не слишком сообразительного человека — оно приобретает эффект синергии при формировании ответного отношения.


V>Это же всё личные кач-ва человека, и они тут сверкают просто как россыпь бриллиантов.

V>В ответ на подобные манеры я обычно включаю свою душевную простоту почти сельского парня, коим и являюсь. ))
Так если и ты стараешься соответствовать, какие претензии к собеседникам?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.