Re[31]: «Собаку съел»
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.01.17 13:57
Оценка: 1 (1)
Здравствуйте, alex_public, Вы писали:

_>Здравствуйте, samius, Вы писали:


S>>Никаких возражений.


_>Ну как бы если размышлять только на уровне исходных кодов, то всё так и есть.

Ок, на уровне исходников пусть так и будет.

_>А вот разница в видах полиморфизма на таком уровне как раз очень важна. Потому как если в языке доступен только ad-hoc, то это будет вынуждать программистов заниматься многократным размножением одного и того же исходного кода. Кстати, в таких случая иногда вообще уходят в другую сторону и применяют вместо всего этого технику "стирания типов". Например с помощью void* в C или Object в ранней Java. Это всё или не безопасно или медленно, но в любом случае крайне не удобно. Однако предпочитают использовать даже такое, только чтобы не заниматься "копипастой".

Вот тут, кстати, написано что void* это небезопасный параметрический полиморфизм во весь рост.

_>Так что на уровне исходных кодов наличие какой-то разновидности параметрического полиморфизма крайне необходимо. А вот на уровне машинных всё наоборот — там оно по нынешним временам только во вред, но об этом ниже.

Это к вопросу о том, что считать благом.

S>>Знал бы Wadler в 88м году что у transform в 2017м будет параметризован 5ю типами...


_>К данному тексту у меня есть три возражения разной важности:


_>1. Мелкое замечание. Не очень хороший пример с размножением transform по специализациям применяемой функции. Дело в том, что transform (да и остальные алгоритмы из STL) принимает в качестве параметра как раз не специализированную, а обобщённую функцию (т.е. f, а не f<int>). А специализация происходит уже внутри, в соответствие с типом элементов переданного контейнера. Так что грубо говоря число "копий" transform(..., ..., ..., f) будет в точности равно числу обрабатываемых типов элементов. Т.е. полиморфная природа f никак не влияет на число копий transform.

это понятно. Но число BinaryFunction влияет. Хотя, есть возможность этим управлять, если зарыть в него косвенность через указатель.

_>2. Про неизбежность распухания кода из-за ad-hoc полиморфизма. Ты всё время при подобных рассуждениях держишь в уме реализацию шаблонов в C++, но это же не единственный вариант. Т.е. понятно что в любом языке на самом низком уровне (в конце концов это АЛУ процессора) лежит ad-hoc полиморфизм, над которым выстраиваются слои параметрического полиморфизма (если он вообще есть). В C++ при компиляции все эти слои интегрируются ради быстродействия. Но мы же уже видели на примере отдельной бинарной сборки apply в Хаскеле, что есть и другие реализации. Т.е. при такой реализации низкоуровневый ad-hoc полиморфизм (оператор равенства в нашем примере) легко изолируется на своём уровне и никак не влияет на природу equal_to. Более того, подобное можно элементарно реализовать и на C++, причём даже без всякой переделки компилятора (а вот переписать всю STL придётся). Только оно будет в разы медленнее текущей реализации, так что и задаром никому не нужно.

На природу equal_to не влияет, но раздувает transform.

_>3. Главное. Даже если забыть в какое время мы живём (когда я скачиваю с сайта фильм в blu-ray качестве (18 ГБ) за 20 минут), то увеличение быстродействия в разы уже давным давно окупает любые распухания кода. Более того, практически все компиляторы (любых языков) имеющие вменяемые оптимизаторы на максимальных уровнях оптимизации увеличивают размер кода. Без всяких шаблонов, полиморфизма и т.п. Просто потому что в основе эффективной оптимизации лежит агрессивный инлайнинг. Т.е. вся индустрия (ну по крайне мере та её часть, где быстродействие хоть что-то значит) стремятся двигаться по этому пути, хотя и не всегда выходит (в том же Хаскеле как только не извращаются, но всё равно выходит медленно), т.к. задача сложная и часто эмпирическая. А в шаблонах C++ это всё даётся с гарантией и так сказать на халяву, по построению. И тут ты говоришь об этом самом распухании как о неком недостатке. Забавно. )

Не совсем верно. Я не пытаюсь кому-либо советовать, как правильно реализовывать комбинации полиморфизмов. Я лишь пытаюсь привлечь твое внимание к тому, какие проблемы решали в 88, оговариваясь что Eq a — это ad hoc, но в меньшей мере ad hoc, чем просто перегрузка.
Ты вообще согласен что Eq a — это ad hoc (о чем написано на каждом заборе)? Если да, то как ты объяснишь свое желание считать equal_to параметрическим, хотя он в большей мере ad hoc, о чем писал Wadler?

S>>А мне не нужно повторять простейший код за C++ на C#. У меня почему-то наоборот. Если я захочу повторить 20К C# строк бизнес логики на C++, то получу 40К строк.


_>Это миф. Потому как в C# имеется только один механизм языка увеличивающий его выразительность и отсутствующий в C++ (причём это продлится только до выхода следующего стандарта C++), а в C++ имеется целый набор таких механизмов, отсутствующих в C#. Так что описанное тобой выше явление может встретится на практике только в одном редком случае: когда для C# имеется готовая библиотека предметной области, а для C++ нет. Такое бывает в некоторых узких областях, но как ты понимаешь к дизайну языка это никакого отношения не имеет.

Это не миф, это результат моего опыта. Да, я в разной степени владею C# и C++. И именно в моем случае скорость развития С++ проекта в разы медленнее, чем скорость развития схожего по сложности проекта на C#. Время компиляции тоже имеет значение. Разработка на C++ в моем случае является драйвером обновления рабочего железа. Как перехожу на C#, я на том же железе могу еще лет 5 комфортно работать.

_>P.S. Последний абзац нашей с тобой дискуссии является полный оффтопиком к самой дискуссии, но при этом на 100% соответствует изначальном сообщению данной темы на форуме. Забавно получилось. )))

Да.
Так что, equal_to — ad hoc?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.