Здравствуйте, 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 через перегрузку) не будет в принципе.
_>>В данном случае функция my_equal_to так же работает с любыми типами имеющими оператор равенства, но при этом она полностью изолирует ad-hoc природу этого оператора внутри себя — она имеет единый и исходный и машинный код для всех типов. По сути похоже на работу внутренностей Хаскеля. И такое же медленное (без всякого инлайнинга). Так что в мире C++ этот механизм используется только для очень специфических целей.
S>Я верю тебе что transform перестает умножаться в таком случае. Но для float и int будет вызываться все же одна машинная инструкция? Или все-таки разные за счет косвенности? Если разные — значит ad hoc (см Wadler88).
Естественно разные, но это всё будет происходить не в теле функции my_equal_to, так что не имеет к ней отношения. Если же ты будешь настаивать в своём определение на учёт внутреннего устройства ещё и всех других функций (вызываемых из обсуждаемой), то тогда у тебя автоматически получится, что вокруг абсолютно всё ad hoc полиморфизм, а параметрического не существует вовсе (потому что на самом низком уровне всё ad hoc).
Более того, при таком подходе у тебя возникает противоречие с собственными же предыдущими утверждениями. Например ты признал что обсуждаемая ранее функция apply (в Хаскеле) — это чистый параметрический полиморфизм без всяких оговорок. Но ведь в том примере в зависимости от типа второго параметра apply (int или float) выполнялся разный код (если смотреть на весь стек вызова, а не только на само тело apply). Т.е. по твоему подходу выше та apply — это тоже ad hoc.
Похоже что ты не смотря на готовность привести различные цитаты других специалистов так и не сумел сформировать у себя в голове непротиворечивое определение для данного явления.
_>>Eq a в данном примере является аналогом не equal_to, а всему множеству операторов равенства в данном C++ проекте. ))) А прямой аналог equal_to вряд ли встретится на практике (хотя пишется элементарно) в Хаскеле и ему подобных языках, просто потому что в отличие от C++ данное мелкое украшательство может оказаться не бесплатным. Кстати, бесплатные многоуровневые абстракции — это как раз одна из ключевых особенностей современного C++.
S>Я имел в виду аналог семантический, а не по реализации. В плане реализации, видимо, Eq a более смахивает на bool my_equal_to, если я правильно понял.
Аналогом my_equal_to в мире Хаскеля будет такой очевидный код:
my_equal_to a b = a==b
Причём данные реализации (C++ и Хаскель) не только выглядят одинаково на уровне исходного кода (и даже имеют по сути одинаковые типы), но и будут крайне похожи на уровне машинного.
S>А бесплатного ничего не бывает.
Бесплатно в смысле производительности и размера программы. Т.е. все эти абстракции живут только на уровне исходного кода, а в машинный не попадают в принципе. Ну а ценой этого можно назвать разве что более долгое (по сравнению с другими языками) время компиляции.
S>>>Так что, equal_to — ad hoc?
_>>Которая std::equal_to? На уровне исходных кодов — нет. На уровне машинных — пожалуй. Точнее на уровне машинных кодов её не будет вовсе, а будет только вставленный на место её вызова код оператора равенства (который ad hoc). Я вроде это всё сказал ещё в самом начале дискуссии.
S>Ок. Осталось выяснить, есть ли вообще в природе классификация полиморфизма, отталкивающаяся от исходных кодов, а не от необходимости выполнения специального кода для разных типов при одинаковой записи.
Выше мы уже выяснили, что если отталкиваться от твоей особенной классификации (которая хочет учитывать наличие специализации кода на всю глубину стека вызовов), то абсолютно всё вокруг является ad hoc полиморфизмом. )))