Здравствуйте, samius, Вы писали:
_>>Для начала напомню, что все последние сообщения у нас идёт дискуссия исключительно о полиморфизме на уровне машинных кодов. Потому что на уровне исходных кодов мы уже давно всё обсудили и пришли к консенсусу, что все версии equal_to (включая шаблонную std::equal_to, с которой всё началось) реализуют параметрический полиморфизм.
S>То ли короткая память, то ли демагогия. Я допускал такое с некоторыми оговорками. Надеюсь, найдешь.
Да, да, я помню. equal_to — это параметрически полиморфизм, но только для тех типов, у которых определён оператор равенства. Только вот с учётом того, что данную функцию собственно и применяют исключительно для работы с такими типами, то смысла от этой оговорки ровно ноль. Но я естественно не возражаю — пускай будет, если тебе так спокойнее. )))
_>>Сейчас же мы уже обсуждаем исключительно генерируемый этими функциями машинный код, т.е. совсем низкий уровень (ассемблерные инструкции и т.п.). И если ты не готов к дискуссии на таком уровне (например оказалось, что ты даже смутно не представляешь какой код генерируется по тем примерам на Хаскеле, что мы обсуждали), то возможно и не стоило её начинать?
S>Ненене, мы не обсуждаем исключительно генерируемый код. Мы обсуждаем классификацию, согласно которой equal_to — ad hoc. В дискуссии об исключительно машинном коде я тебе не оппонент. Т.к. я не видал классификаций, которые бы говорили об исключительно машинном коде. Если это ты их выдумал, то приведи их и скажи, что это ты выдумал. Если подглядел где — сошлись на источник.
Что-то у тебя какая-то короткая память. Это как раз я неоднократно заявлял, что лично мне более чем достаточно факта параметрического полиморфизма на уровне исходного кода, а что там творится в машинных кодах вообще не принципиально. А ты наоборот начал говорить о важности анализа машинных кодов, чем мы и занялись. Правда в итоге оказалось, что в данной области ты очень слабо разбираешься, так что это твоё желание углубиться на уровень машинных кодов действительно очень странно. Но если ты посмотришь на историю сообщений в данной теме, то легко увидишь, что это было именно твоё желание.
_>>Далее, если говорить про анализ машинных кодов, то там опять же не всё так страшно (произвольно), как тебе мерещится. Во-первых все ключевые вопросы чётко зафиксированы в документациях (открой например стандарт C++ — там чётко указано какие нюансы отдаются на откуп оптимизатору, а каких должны быть фиксированы — на них можно рассчитывать и при программирование под микроконтроллер и под мейнфрейм). А во-вторых, даже если говорить о нюансах зависящих от оптимизатора, то их точно так же можно без проблем обсуждать в деталях. Только при этом необходимо фиксировать в разговоре версии компилятора и опции его запуска, а так же не бояться такой штуки как дизассемблер. И кстати на этом форуме было уже множество дискуссий на таком уровне, с собеседниками имеющими нормальные познания в области оптимизации. Однако мы с тобой в данной дискуссии даже отдалённо не приблизились к подобному уровню — все наши примеры полностью укладывались в самые базовые сценарии генерации кода.
S>Ты заметил у Пирса фиксацию версии компилятора в определении или классификации полиморфизма? Я — нет. Может в википедии? Если тоже нет — значит ты увиливаешь от темы.
Вот не надо передёргивать мои слова до вообще обратного смысла. Я здесь как раз отметил тот факт, что в нашей дискуссии
не требуется подобное, потому как все важные для неё нюансы укладываются в документации, а не являются произволом оптимизаторов. Т.е. в обсуждаемых нами вопросах кивать на некую "произвольность реализации", выдаваемую компилятором нельзя.
S>Не хочешь — не надо, я ж тебя не заставляю. Оставим просто как есть. Пирс, википедия, хаскельвики за ad hoc equal_to. Твое мнение никто не разделяет.
Ну а это уже откровенное враньё.
_>>Ну и возвращаясь к твоему ответу на мой вопрос. И так, ты значит выбрал позицию, что для анализа вида полиморфизма некой функции, надо проанализировать не только её машинный код, но и машинный код всех функций в её стеке вызова. Ну правда с какой-то там оговоркой, но это даже веселее в итоге будет. )))
_>>Раз так, то тогда тебя конечно же не затруднит расшифровать почему ad hoc оператор сложения (находящийся в стеке вызова функции apply из нашего примера на Хаскеле) не должен учитываться при анализе функции apply (она же у нас параметрически полиморфная в том числе и по твоему мнению). Видимо это действие той самой магической оговорки? Или нет?
S>Что ей передали первымм аргументом, то и будет в стеке. Передали ad-hoc функцию, получился в стеке ad-hoc, Передали параметрическую — значит в стеке нет ad-hoc. Не смущает неоднозначность такого подхода?
А причём тут я? У меня то совсем другая точка зрения (в которой надо смотреть только на тело функции и в которой все обсуждаемые параметрически полиморфны), в которой никаких противоречий нет. А вот тебя, с твоими противоречивыми взглядами это действительно должно смущать.
Так, значит мы уже дошли в наших рассуждениях (изучение следствий из твоей позиции) до того факта, что вид полиморфизма apply нельзя определить по её коду — он зависит от параметров. И у нас уже есть пример, который демонстрирует (если придерживаться твоих взглядов) ad-hoc поведение apply. Теперь пойдём ещё чуточку дальше: а давай посмотрим, есть ли вообще такие параметры, при которых apply параметрически полиморфна? Ну кроме случая реализации константной функции и ему подобных столько же полезных и часто употребимых на практике примеров. )))
_>>Ну а после твоего ответа я конечно же ещё спрошу почему эти же аргументы не применимы для абсолютно аналогичного случая ad hoc оператора равенства, находящегося в стеке вызова функции my_equal_to.
S>Потому что оператор равенства разный для разных типов. У него разные поведения, разные математические свойства в зависимости от типа. Если ты подсунешь в my_equal_to единый способ сравнения для всех типов (не использующий штатные перегрузки оператора ==), то она станет параметрической, но какое отношение она будет иметь к сравнению через оператор равенства — вопрос отдельной дискуссии.
Ну вот видишь, ты же сам тут указал, что при таком подходе вид полиморфизма my_equal_to ничем не отличается от apply — зависит от внешних факторов (устройства функции f или оператора равенства для типа eq).
_>>Ну если следовать твоему определению (с исследованием всего стека вызова), то скорее всего ровно ноль. Потому что я что-то сомневаюсь в наличие в твоём приложение этой очаровательной константной функции. )))
S>Приведи, пожалуйста, мое определение (с исследованием всего стека вызова)? Я что-то запамятовал, что бы я давал такое определение (вообще свое). Я отлично пользуюсь чужими, мне нет смысла давать свое.
Пару сообщений назад я попросил тебя зафиксировать свою позицию по данному вопросу, что ты и сделал далее. Дать ссылку на твою цитату или сам найдёшь? )
_>>Притом что:
_>>1. Именно по это причине Хаскель работает не так, как тебе воображалось
_>>2. Именно по этой причине любой вменяемый (знающий хотя бы основы функционирования современных ЦПУ) программист знал бы правильный ответ без обращения к документации ghc. Так что твои заблуждения в данной области наводят на определённые мысли...
S>Ну работает не так, работает чуть быстрее, чем мне воображалось. От этого поменялась классификация?
От этого поменялся генерируемый машинный код. Соответственно, если ты настаиваешь на сравнение машинных кодов (причём на всю глубину стека вызовов) для выявления вида полиморфизма, то вполне может поменяться и классификация.
_>>Эм, ты даже такой очевидный текст не можешь нормально воспринять? ) Генерируется ровно один машинный код данной функции. Самый обычный (не с одним аргументом), который ты можешь положить в отдельный бинарный файл. И все вызовы вида "apply f 1" и т.п. (с полным набором аргументов) будут осуществлять прямой вызов этой функции. 80% кода на Хаскеле попадает именно в эту категорию (по этому и более менее шевелится). Плюс к этому, если где-то в приложение встретится отдельная конструкция вида "apply f", то будет сгенерирована (в уже другом бинарном модуле) ещё одна функция, реализующая частичное применение функции apply (естественно через вызов изначальной).
S>О, то есть еще одна все-таки бывает. Спасибо, что подтвердил то что я "не смог нормально воспринять".
Мда, похоже примеры с устройством Хаскеля реально слишком сложные. Давай проясним глупость твоих фраз (про "несколько тел для одной функции" и т.п.) на простейшем C++ примере, который аналогичен (если опять же собирать в отдельных бинарных модулях, а то иначе инлайнинг вообще убьёт все эти функции) внутреннему устройству Хаскеля:
auto f=[](int x, int y) {return x+y;};
auto g=[](int y) {return f(1, y);};
f(1, 2);
Так вот, по этому коду можешь ли ты сказать что:
1. вторая строчка хоть как-то влияет на третью
2. что компилятор генерирует несколько тел для функции f.
И если не можешь, то почему говоришь аналогичный бред про случай с Хаскелем? )