Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, samius, Вы писали:
S>>Дада, я вот тоже для тебя западню заготовил, но вот беда (и смешно и обидно вышло... ) переоценил уровень твоего бэкграунда. И ты пролетел мимо этой засады, даже не поморщился. Ну что ж, попробую тебя оттормозить, оттащить назад и все-таки посадить в эту лужу.
_>Давно не видел такого длинного и при этом бессмысленного (одна вода) текста на данном форуме. Ну да ладно, попытаюсь вычленить из него хоть какие-то тезисы.
Жаль, что не вычленил про поведение. Ну да ладно.
_>Для начала напомню, что все последние сообщения у нас идёт дискуссия исключительно о полиморфизме на уровне машинных кодов. Потому что на уровне исходных кодов мы уже давно всё обсудили и пришли к консенсусу, что все версии equal_to (включая шаблонную std::equal_to, с которой всё началось) реализуют параметрический полиморфизм.
То ли короткая память, то ли демагогия. Я допускал такое с некоторыми оговорками. Надеюсь, найдешь.
_>Сейчас же мы уже обсуждаем исключительно генерируемый этими функциями машинный код, т.е. совсем низкий уровень (ассемблерные инструкции и т.п.). И если ты не готов к дискуссии на таком уровне (например оказалось, что ты даже смутно не представляешь какой код генерируется по тем примерам на Хаскеле, что мы обсуждали), то возможно и не стоило её начинать?
Ненене, мы не обсуждаем исключительно генерируемый код. Мы обсуждаем классификацию, согласно которой equal_to — ad hoc. В дискуссии об исключительно машинном коде я тебе не оппонент. Т.к. я не видал классификаций, которые бы говорили об исключительно машинном коде. Если это ты их выдумал, то приведи их и скажи, что это ты выдумал. Если подглядел где — сошлись на источник.
_>Далее, если говорить про анализ машинных кодов, то там опять же не всё так страшно (произвольно), как тебе мерещится. Во-первых все ключевые вопросы чётко зафиксированы в документациях (открой например стандарт C++ — там чётко указано какие нюансы отдаются на откуп оптимизатору, а каких должны быть фиксированы — на них можно рассчитывать и при программирование под микроконтроллер и под мейнфрейм). А во-вторых, даже если говорить о нюансах зависящих от оптимизатора, то их точно так же можно без проблем обсуждать в деталях. Только при этом необходимо фиксировать в разговоре версии компилятора и опции его запуска, а так же не бояться такой штуки как дизассемблер. И кстати на этом форуме было уже множество дискуссий на таком уровне, с собеседниками имеющими нормальные познания в области оптимизации. Однако мы с тобой в данной дискуссии даже отдалённо не приблизились к подобному уровню — все наши примеры полностью укладывались в самые базовые сценарии генерации кода.
Ты заметил у Пирса фиксацию версии компилятора в определении или классификации полиморфизма? Я — нет. Может в википедии? Если тоже нет — значит ты увиливаешь от темы.
Не хочешь — не надо, я ж тебя не заставляю. Оставим просто как есть. Пирс, википедия, хаскельвики за ad hoc equal_to. Твое мнение никто не разделяет.
_>Ну и возвращаясь к твоему ответу на мой вопрос. И так, ты значит выбрал позицию, что для анализа вида полиморфизма некой функции, надо проанализировать не только её машинный код, но и машинный код всех функций в её стеке вызова. Ну правда с какой-то там оговоркой, но это даже веселее в итоге будет. )))
_>Раз так, то тогда тебя конечно же не затруднит расшифровать почему ad hoc оператор сложения (находящийся в стеке вызова функции apply из нашего примера на Хаскеле) не должен учитываться при анализе функции apply (она же у нас параметрически полиморфная в том числе и по твоему мнению). Видимо это действие той самой магической оговорки? Или нет?
Что ей передали первымм аргументом, то и будет в стеке. Передали ad-hoc функцию, получился в стеке ad-hoc, Передали параметрическую — значит в стеке нет ad-hoc. Не смущает неоднозначность такого подхода?
_>Ну а после твоего ответа я конечно же ещё спрошу почему эти же аргументы не применимы для абсолютно аналогичного случая ad hoc оператора равенства, находящегося в стеке вызова функции my_equal_to.
Потому что оператор равенства разный для разных типов. У него разные поведения, разные математические свойства в зависимости от типа. Если ты подсунешь в my_equal_to единый способ сравнения для всех типов (не использующий штатные перегрузки оператора ==), то она станет параметрической, но какое отношение она будет иметь к сравнению через оператор равенства — вопрос отдельной дискуссии.
_>>>Где-то в моём примере объявлена или используется функция вида "g = apply f"? ) Не надо подобных дешёвых фокусов.
S>>В том, что касается дешевых фокусов, используя понятие процедурной абстракции, можно верить тому, что поведение функции apply f не отличимо от поведения функции f, и оно же неотличимо от "g = apply f". Если бы это было не так, то функцию apply с аргументом f нельзя было бы использовать вместо функции f. Но ты ее как раз используешь исходя из сохранения поведения. Значит, должен быть удовлетворен любой подстановкой с сохранением его. Если нет — выполняй f сам.
_>Объясняю ещё раз на доступном языке. Мы здесь изучаем поведение машинных кодов. Если ты нигде не использовал явно функцию вида "apply f" (а в моём примере такого не было), то в машинных кодах её не будет существовать в принципе. Более того, даже если ты где-то в проекте и используешь её (так что в итоге подобный код будет существовать в итоговом исполняемом файле), то в процессе выполнения моих примеров она всё равно вызываться не будет (всё равно будет прямой вызов нормальной apply с двумя параметрами). Теперь понятно? )
Что это меняет?
_>>>А, ну да) Остроумно. ))) И много таких функций встречается в твоих приложениях? )
S>>О, рад что ты оценил. Да, параметрически полиморфных функций в моих приложениях встречается много.
_>Ну если следовать твоему определению (с исследованием всего стека вызова), то скорее всего ровно ноль. Потому что я что-то сомневаюсь в наличие в твоём приложение этой очаровательной константной функции. )))
Приведи, пожалуйста, мое определение (с исследованием всего стека вызова)? Я что-то запамятовал, что бы я давал такое определение (вообще свое). Я отлично пользуюсь чужими, мне нет смысла давать свое.
А наличие в моем приложении константной функции отношения к твоему утверждению что абсолютно все ad hoc (согласно анализу стека) — вообще никакого нет. Ладно, запишемм что ты гиперболировал. В лужу.
_>>>Ты вот что, серьёзно верил, что каррирование реально существует на уровне машинных кодов? Да если бы кто-то и попытался сделать подобное, то оно работало бы не просто медленно (как нынешний Хаскель), а вообще почти не шевелилось бы (наверное хуже чем какой-нибудь bash).
S>>Ну причем тут "медленно"?
_>Притом что:
_>1. Именно по это причине Хаскель работает не так, как тебе воображалось
_>2. Именно по этой причине любой вменяемый (знающий хотя бы основы функционирования современных ЦПУ) программист знал бы правильный ответ без обращения к документации ghc. Так что твои заблуждения в данной области наводят на определённые мысли...
Ну работает не так, работает чуть быстрее, чем мне воображалось. От этого поменялась классификация?
_>>>https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/HaskellExecution/FunctionCalls — на вот, просвещайся как обстоят дела в реальности, чтобы не писать больше подобных глупостей.
S>>Вот видишь, согласно понятию процедурной абстракции хаскель может генерить несколько различных тел для одной функции и вызывать их в зависимости от обстоятельств вызова. Сохраняя, при этом поведение, соответствующее execution model. Если завтра технические детали реализации поменяются с "просто медленно" на "вообще почти не шевелилось бы", но сохранится execution model, то на поведение функций apply, f, apply f это не повлияет. Следовательно, сохранится их параметрическая классификация. Будь уверен в этом.
_>Эм, ты даже такой очевидный текст не можешь нормально воспринять? ) Генерируется ровно один машинный код данной функции. Самый обычный (не с одним аргументом), который ты можешь положить в отдельный бинарный файл. И все вызовы вида "apply f 1" и т.п. (с полным набором аргументов) будут осуществлять прямой вызов этой функции. 80% кода на Хаскеле попадает именно в эту категорию (по этому и более менее шевелится). Плюс к этому, если где-то в приложение встретится отдельная конструкция вида "apply f", то будет сгенерирована (в уже другом бинарном модуле) ещё одна функция, реализующая частичное применение функции apply (естественно через вызов изначальной).
О, то есть еще одна все-таки бывает. Спасибо, что подтвердил то что я "не смог нормально воспринять".
Очень мило что ты замел под ковер свой косяк с трактоваками поведения функции. Считаю это еще одним признаком моей правоты.