Здравствуйте, 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>В ответ на подобные манеры я обычно включаю свою душевную простоту почти сельского парня, коим и являюсь. ))
Так если и ты стараешься соответствовать, какие претензии к собеседникам?