Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, samius, Вы писали:
_>>>Кстати, в C++ имеется своя, полностью безопасная техника стирания типа: http://www.boost.org/doc/libs/1_63_0/doc/html/boost_typeerasure.html. И с помощью неё можно элементарно написать аналог equal_to, который будет демонстрировать параметрический полиморфизм не только на уровне исходного кода, но и на уровне машинного:
S>>вот тут я по поводу машинного не согласен.
S>>Ты Вадлера88 посмотрел? Ввел он типы классов, перестало быть сравнение ad hoc? Нет, статья прям и называется "Как из ad hoc сделать меньше ad hoc". Т.е. типы классов в Хаскеле — ad hoc, как ни крути, но в меньшей степени, чем перегрузка. И это не я придумал.
_>В смысле не согласен? Машинный код одинаков для всех типов с точностью до бита (эту функции в отличие от шаблонной можно скомпилировать в отдельный бинарный модуль). Это просто факт, с которым ничего нельзя поделать.
Машинный код сравнения двух значений не может быть независимым от типов этих значений. Эти значения просто нельзя начинать сравнивать, не зная их тип. Значит, если код твоей функции от типов не зависит, то он должен принять нечто, что позволит косвенно перейти к специализации сравнения. Классы типов хаскеля — это и есть эта косвенность.
А раз есть косвенность, значит есть и зависимость от специализации. А значит — ad hoc.
_>Если же ты снова намекаешь на то, что данная реализация функции определена не для всех возможных типов (а только для имеющих оператор равенства), то это ничего не меняет. Потому что только для таких типов эта функция и будет использоваться — других вариантов (которые теоретически могли бы создать тот самый ad hoc через перегрузку) не будет в принципе.
Но для тех типов будет выполнен разный код сравнения, специальный для каждого типа? Я не про верхнюю функцию я про именно самый низкий уровень сравнения. Если разный — значит функция верхнего уровня, использующая эти разные коды — ad hoc. И я тут не намекаю уже. КРИЧУ!
S>>Я верю тебе что transform перестает умножаться в таком случае. Но для float и int будет вызываться все же одна машинная инструкция? Или все-таки разные за счет косвенности? Если разные — значит ad hoc (см Wadler88).
_>Естественно разные, но это всё будет происходить не в теле функции my_equal_to, так что не имеет к ней отношения. Если же ты будешь настаивать в своём определение на учёт внутреннего устройства ещё и всех других функций (вызываемых из обсуждаемой), то тогда у тебя автоматически получится, что вокруг абсолютно всё ad hoc полиморфизм, а параметрического не существует вовсе (потому что на самом низком уровне всё ad hoc).
1) я не знаю, почему ты определение называешь моим, оно везде. А вот твое я нигде не нашел более (а источник ты не указал).
2) нет, не получается автоматически. Ты передергиваешь.
Разреши, я тебе подскажу лайфках. Есть такая страничка
https://wiki.haskell.org/Polymorphism и в частности
https://wiki.haskell.org/Polymorphism#Ad-hoc_polymorphism.
Там написано, какие функции в Хаскеле параметрически (абсолютно) полиморфны, а какие — ad hoc.
И на тот случай, если ты не станешь читать (а vdimas не стал), я процитирую оттуда параграф (vdimas-у уже цитировал, но ты ведь не читаешь мои ответы ему).
You can recognise the presence of ad-hoc polymorphism by looking for constrained type variables: that is, variables that appear to the left of =>, like in elem :: (Eq a) => a -> [a] -> Bool. Note that lookup :: (Eq a) => a -> [(a,b)] -> Maybe b exhibits both parametric (in b) and ad-hoc (in a) polymorphism.
Я не знаю, будешь ли ты спорить с хаскельвики, но эта цитата по-крайней мере является свидетельством того, что не я один придерживаюсь определения, авторство которого ты приписываешь мне. Если, конечно, я не подправил хаскельвики.
_>Более того, при таком подходе у тебя возникает противоречие с собственными же предыдущими утверждениями. Например ты признал что обсуждаемая ранее функция apply (в Хаскеле) — это чистый параметрический полиморфизм без всяких оговорок. Но ведь в том примере в зависимости от типа второго параметра apply (int или float) выполнялся разный код (если смотреть на весь стек вызова, а не только на само тело apply). Т.е. по твоему подходу выше та apply — это тоже ad hoc.
Prelude> apply f a = f a
Prelude> :t apply
apply :: (t -> t1) -> t -> t1
Видишь? вовсе не ad hoc.
_>Похоже что ты не смотря на готовность привести различные цитаты других специалистов так и не сумел сформировать у себя в голове непротиворечивое определение для данного явления.
Вовсе нет. То что оно противоречит с твоими убеждениями (и vdimas-а тоже) — не беда вовсе. Для меня важнее что оно не противоречит с классикой, википедией и даже хаскельвики.
_>Аналогом my_equal_to в мире Хаскеля будет такой очевидный код:
_>_>my_equal_to a b = a==b
_>
_>Причём данные реализации (C++ и Хаскель) не только выглядят одинаково на уровне исходного кода (и даже имеют по сути одинаковые типы), но и будут крайне похожи на уровне машинного.
тадам....
Prelude> my_equal_to a b = a==b
Prelude> :t my_equal_to
my_equal_to :: Eq a => a -> a -> Bool
ad hoc.
S>>А бесплатного ничего не бывает.
_>Бесплатно в смысле производительности и размера программы. Т.е. все эти абстракции живут только на уровне исходного кода, а в машинный не попадают в принципе. Ну а ценой этого можно назвать разве что более долгое (по сравнению с другими языками) время компиляции.
О, расплата за бесплатное все-таки существует.
S>>Ок. Осталось выяснить, есть ли вообще в природе классификация полиморфизма, отталкивающаяся от исходных кодов, а не от необходимости выполнения специального кода для разных типов при одинаковой записи.
_>Выше мы уже выяснили, что если отталкиваться от твоей особенной классификации (которая хочет учитывать наличие специализации кода на всю глубину стека вызовов), то абсолютно всё вокруг является ad hoc полиморфизмом. )))
Я надеюсь, что мы все же выяснили, что это не моя классификация.
apply — не является (см цитату выше). Ну и в хаскельвики еще пару примеров упомянуто.
А с помощью :t, я думаю, ты сможешь найти достаточное количество примеров, что бы твой переход от моего лица к "абсолютно все является ad hoc" выглядел бы наигранным.