Здравствуйте, so5team, Вы писали:
S>Здравствуйте, a7d3, Вы писали:
A>>Долго спорили за виды полиморфизма в ООП применимо к С++ (в RAII и исключения в конструкторе) A>>А вот пример https://habr.com/ru/company/samsung/blog/505850/ A>>того, что давно используется без претензий на отдельную парадигму, выходящую за пределы ООП.
S>А вот интересно, здесь вы тоже ООП отыщите?
Опять демонстрация подхода — кидать ссылки, но при этом не смотреть таковые?
Сразу под заголовком видно, что её уже давно определили в ООП-хаб
И, да, это комично в 2016-м рассказывать о том, что используется чуть ли не со времён BCC 3.1 (Borland C++ от 1992-го года).
Ясно, что человеку хочется пиарить свою особо ценную библиотечку на том же хабре и для этого типа «прокачивает», но смотрится это по-идиотски.
Надо подкинуть ему идею рассказать такой же статейкой про The Curiously Recurring Template Pattern (CRTP) — сто процентов не промахнётся
Здравствуйте, a7d3, Вы писали:
S>>А вот интересно, здесь вы тоже ООП отыщите?
A>Сразу под заголовком видно, что её уже давно определили в ООП-хаб
Т.е. для вас критерий ООП/неООП -- это название хаба на Хабре?
A>И, да, это комично в 2016-м рассказывать о том, что используется чуть ли не со времён BCC 3.1 (Borland C++ от 1992-го года).
Вопрос был не про новизну идеи. А про то, найдете ли вы там ООП или нет.
Здравствуйте, PM, Вы писали:
PM>Насколько я понял, это просто список функций, вызываемых последовательно, одна за другой. Зачем-то его обзвали Manager
PM>Так можно написать на любом языке, где функции являются полноценными гражданами, хоть на Haskell, хоть на JavaScript. Ну и на C++ само собой.
std::function & lambda появились в плюсах «недавно» и в результате увлечения функторами, вместо указателей на «свободные функции».
А обозвали manager, скорее всего, из-за возможности добавлять-удалять проходы. Вряд ли из-за древовидной структуры произвольной вложенности, которые у них лепятся из этих манагеров-прохода.
Давайте посмотрим на код, в чем здесь проблема? Мы видим, что в этой иерархии методы запуска прохода различны в зависимости от того, над чем они должны выполняться (над функцией — runOnFunction, модулем — runOnModule, циклом — runOnLoop и тд). В свою очередь, это делает невозможным обрабатывать коллекцию проходов, которые работают с разными IR сущностями, единым способом (собственно применять полиморфизм). Казалось бы, очевидно, как сделать правильно: нужен виртуальный метод run, который будет переопределяться в наследниках. Но тут же возникает проблема: у методов run в классах-наследниках будет разная сигнатура, поскольку передается параметр всегда своего типа — функция, модуль и так далее. Значит, придется делать фиктивный базовый класс для Module, Function и т.д., передавать в run указатель на этот класс, а внутри метода делать down-cast, в зависимости от того, что за объект находится по данному указателю. И начинается что-то странное: при появлении новой нижестоящей сущности мы вынуждены теперь переписывать каждый раз вышестоящий код, что противоречит всем принципам проектирования.
Вместо того, чтобы добавить честные шаблонные виртуальные функции в язык (это же писатели компилятора или кто?) занимаются поиском обходных путей...
Здравствуйте, a7d3, Вы писали:
S>>Вопрос был не про новизну идеи. А про то, найдете ли вы там ООП или нет.
A>Таки усё ишо зудит с предыдущего диалога? A>Охота и здесь поговорить «за ООП в целом» — не опять, а снова?
Сказал персонаж, которому было не лень создать новую тему для "утверждения" своей точки зрения.
Тем не менее, на вопрос сможете ответить или в очередной раз надуете щеки и заявите, что вам не пристало общаться с быдл колхозником?
Здравствуйте, B0FEE664, Вы писали:
BFE> BFE>Вместо того, чтобы добавить честные шаблонные виртуальные функции в язык (это же писатели компилятора или кто?) занимаются поиском обходных путей...
Это Роман Русяев
Expert Engineer
AI Compiler Team
Samsung R&D Institute, Russia
Занимается разработкой компилятора нейронных сетей для NPU (Neural Processing Unit) в российском центре Samsung R&D. Скомпилированные нейронные сети поставляются в составе флагманских телефонов Samsung, таких как Galaxy Note 10.
Имеется опыт разработки оптимизирующего компилятора под VLIW-архитектуру «Эльбрус» и архитектуру SPARC с языков C, C++, Fortran. В процессе разработки оптимизирующего компилятора, занимался реализацией:
платформозависимых и платформонезависимых оптимизаций;
оптимальной обработки исключений С++ (zero-cost exception handling) в части middle-end компилятора;
санитайзеров: AddressSanitizer, MemorySanitizer, LeakSanitizer, включая портирование библиотеки compiler-rt на платформу «Эльбрус».
Здравствуйте, so5team, Вы писали:
S>Сказал персонаж, которому было не лень создать новую тему для "утверждения" своей точки зрения.
S>Тем не менее, на вопрос сможете ответить или в очередной раз надуете щеки и заявите, что вам не пристало общаться с быдл колхозником?
Если будет говорить про вот этот самый вид полиморфизма, то почему бы и не подискутировать?
А коли он опять в своём маня мирке — приписывает другим людям свои выдумки — и хочет трендеть на другие темы, то ему дорога лишь к собутыльникам.
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, a7d3, Вы писали:
A>>Если будет говорить про вот этот самый вид полиморфизма, то почему бы и не подискутировать?
S>Да блин, вы на простой вопрос ответить в состоянии? Есть код, видите ли в этом коде ООП или нет?
Ещё раз — учимся самодисциплине, прекращаем оффтоп.
Здравствуйте, a7d3, Вы писали:
BFE>> BFE>>Вместо того, чтобы добавить честные шаблонные виртуальные функции в язык (это же писатели компилятора или кто?) занимаются поиском обходных путей...
A>Это Роман Русяев
К чему нам эти персональные данные?
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, a7d3, Вы писали:
BFE>>> BFE>>>Вместо того, чтобы добавить честные шаблонные виртуальные функции в язык (это же писатели компилятора или кто?) занимаются поиском обходных путей...
A>>Это Роман Русяев BFE>К чему нам эти персональные данные?
Здравствуйте, a7d3, Вы писали:
PM>>Насколько я понял, это просто список функций, вызываемых последовательно, одна за другой. Зачем-то его обзвали Manager PM>>Так можно написать на любом языке, где функции являются полноценными гражданами, хоть на Haskell, хоть на JavaScript. Ну и на C++ само собой. A>std::function & lambda появились в плюсах «недавно» и в результате увлечения функторами, вместо указателей на «свободные функции».
И что? Технология Signals and slots придумана была ещё до Qt (хотя Википедия врёт об обратном). В отличии от статического и динамического полиморфизма, полиморфизм основанный на Signals and slots является параметрическим полиморфизм, а введение lambda и вариадик параметров делает такой полиморфизм строготипизированным (при желании). При этом, в отличии от других, полиморфизм основанный на Signals and slots позволяет связывать вызовы объектов, которые ничего не знают друг о друге и полностью независимы. Информация о типах нужна только в точке их связывания.
В частности, вместо:
template <typename IR, typename... ArgTs> class PassManager {
std::vector<std::unique_ptr<detail::PassConcept<IR, ArgTs...>>> Passes;
};
можно использовать:
template <typename IR, typename... ArgTs> class PassManager {
std::vector<std::function<R, Args...>> Passes;
};
в качестве элемента в Passes можно добавить функтор хранящий указатель на произольный объект PassT (например лямбду, где в captures захватывается объект для вызова) и тогда ни PassModel, ни PassConcept будут не нужны.
Единственная проблема с таким подходом — скорость выполнения (хотя, кто её измерял?). При этом, если вместо обобщённых std::function и лямбды написать свои обёртки, то скорость тожно не будет хуже, чем вызов функции через указатель на неё.
Здравствуйте, B0FEE664, Вы писали:
BFE>В отличии от статического и динамического полиморфизма, полиморфизм основанный на Signals and slots является параметрическим полиморфизм
А чем статический полиморфизм отличается от параметрического?
Давайте посмотрим на код, в чем здесь проблема? Мы видим, что в этой иерархии методы запуска прохода различны в зависимости от того, над чем они должны выполняться (над функцией — runOnFunction, модулем — runOnModule, циклом — runOnLoop и тд). В свою очередь, это делает невозможным обрабатывать коллекцию проходов, которые работают с разными IR сущностями, единым способом (собственно применять полиморфизм). Казалось бы, очевидно, как сделать правильно: нужен виртуальный метод run, который будет переопределяться в наследниках. Но тут же возникает проблема: у методов run в классах-наследниках будет разная сигнатура, поскольку передается параметр всегда своего типа — функция, модуль и так далее.
Вот очевидно же, что раз "у методов run в классах-наследниках будет разная сигнатура", то её и надо поддержать. Т.е. сделать run шаблонным виртуальным методом. Но автор делает странный вывод:
Значит, придется делать фиктивный базовый класс для Module, Function и т.д.