Здравствуйте, IT, Вы писали:
T>>В то же время у меня есть опыт редукции офигительной объектно-ориентированной иерархии на C++ из десятка шаблонных классов и активным использованием STL и Boost на полсотни килобайт кода в одну (!) функцию на C из сорока строчек, *не использующую даже CRT*. И я совершенно уверен из всего своего опыта -- любая "сложность" программирования на простых языках без лишних фич во многом надумана. C is really enough. IT>Нет таких алгоритмов, которые можно сделать на C и нельзя сделать на том же C# так же или проще. Обратное неверно. Возьми хотя бы замыкания.
Обратное верно, если учесть хотя бы низкоуровневую специфику, которую часто на C# или реализовать нельзя, или только unmanaged кодом (который лучше считать диверсией, а не C#, по крайней мере в рамках данной дискуссии). Но и замыкания — ни капельки не rocket science. Везде, где интерфейс написан нормально (а не через двуединую сущность с вертикальной улыбкой) и есть передача указателя на callback, есть и передача произвольного параметра (как правило, void*) к этому коллбэку. Если мы подменим и функцию (на свою) и данные (заведя структуру с исходным указателем и сохранёнными данными), получим то же замыкание. Да, это "закат солнца вручную" и грабли этого подхода известны. Но тем не менее — работает и используется.
Я подобный механизм использовал на C, и мне его понять было значительно легче, чем замыкания, в которых косвенным и изначально неочевидным образом фиксируются значения переменных. Фактически, замыкания в известных ФЯ и приближенных к них, таких, как Perl, Python... — хак на основании того, что ссылка на копию значения запоминается через неявное средство обеспечения уникальной копии (для процедурно функционально-обогащённых;)) языков это персональный стековый фрейм).
(О, какой термин прикольный родился на ходу — надо запомнить.)
T>>Сейчас все эти сишарпы и немерле выплывают только на растущей производительности компов, которая пока растёт быстрее чем все их сборщики мусора тормозят. Надолго ли? IT>Это всё домысла. GC работает вполне приемлемо. А вот от объема того функционала, который делается сегодня современными средствами, любой C очень быстро захлебнётся в собственном дерь... простите в malloc, free и char*.
С этим полностью согласен — сила современных языков не столько в том, что они позволяют, сколько в том, что они не позволяют и в какие рамки укладывают применяемые средства.
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, yumi, Вы писали:
Y>>:)) Верить я тебе на слово не буду, извини. Я незнаю как там в вашем Питоне, может там и действительно хреново получается делать функциональную декомпозицию, а вот по крайней мере в Хаскеле (и Лиспе тоже) это делается очень естесственно.
FR>В питоне также естественно. FR>ФВП полноценные плюс динамика и утиная типизация. FR>И кстати как раз в питоне можно совсем без наследования прожить.
Можно, не спорю. Но удобно ли?
Не так давно добавлял одну функциональность к группе классов, прежде объединённых именно утиной типизацией (у них не было общего предка, были только одинаковые методы, но с заметно разной реализацией). Потребовалось добавить функциональность (асинхронная отработка вызова, причём с сериализацией адекватной задаче — несколько объектов фильтра могут использовать один прокси, но отрабатывать это должен тред, связанный с данным прокси). Оказалось, что надо писать почти один и тот же код (очень много общего) во всех классах фильтров. Вопрос — как это сделать?;)) Фактически получалось два варианта:
первый — как предлагает коллега yumi, примерно так:
class BasicFilter:
def ein(self):
...
def eout(self):
...
class Filter1(BasicFilter):
...
А теперь вопрос в студию — и нафига корячиться с явным списком по первому типу, опять-таки дублируя кучу кода с этими назначениями методов (или — как альтернатива — их явными вызовами в методах в каждом классе)? Второй вариант делает то же самое, требует минимальных затрат на понимание, проще в сопровождении, не даёт глупого дублирования, сокращает проблемы от описок. Я — всецело за него:))
А если кто-то хочет сказать, что это не наследование, а специализация — мне как-то здесь без разницы.:)
Здравствуйте, McSeem2, Вы писали:
MS>Здравствуйте, IT, Вы писали:
IT>>Я сразу начну писать код прямо в методе Main и только когда почувствую дискомфорт, озабочусь иерархией классов.
MS>Слушай, Игорь, но почему именно "озабочусь иерархией классов"? Что, без наследования в современном мире не прожить? Лично я считаю парадигму наследования самым противоестественным самодурством какого-то одного горе-теоретика, типа авторитета, которому удалось запудрить мозги всем и надолго. Я это уже говорил что инкапсуляция и полиморфизм — 256 раз да! Наследованию — отказать. Парадигма наследования в программировании компьютеров — это пожалуй второй по величине фуфлоид.
IT>>Делать это сразу я не стану, т.к. считаю это бесполезной тратой времени, потому что не знаю, что меня ждёт впереди.
MS>Согласен! Лично для меня первична алгортмическая сущность — на уровне получится или нет и что можно выжать из этого именно на алгортмическом уровне. Это для меня — самая сложная и самая интересная часть задачи. А уж обернуть в классы и иерархии, плюс кодовая оптимизация — это рутина, этим пусть мальчики-архитекторы и мальчики-кодеры занимаются. Я всегда готов их проконсультировать и объяснить сущность алгоритма.
самый большой проект, в котором ты когда-либо участвовал?
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, FR, Вы писали:
FR>>Здравствуйте, yumi, Вы писали:
Y>>> Верить я тебе на слово не буду, извини. Я незнаю как там в вашем Питоне, может там и действительно хреново получается делать функциональную декомпозицию, а вот по крайней мере в Хаскеле (и Лиспе тоже) это делается очень естесственно.
FR>>В питоне также естественно. FR>>ФВП полноценные плюс динамика и утиная типизация. FR>>И кстати как раз в питоне можно совсем без наследования прожить.
N>Можно, не спорю. Но удобно ли?
Если пишешь в нужном стиле то вполне
N>Не так давно добавлял одну функциональность к группе классов, прежде объединённых именно утиной типизацией (у них не было общего предка, были только одинаковые методы, но с заметно разной реализацией). Потребовалось добавить функциональность (асинхронная отработка вызова, причём с сериализацией адекватной задаче — несколько объектов фильтра могут использовать один прокси, но отрабатывать это должен тред, связанный с данным прокси). Оказалось, что надо писать почти один и тот же код (очень много общего) во всех классах фильтров. Вопрос — как это сделать?) Фактически получалось два варианта:
Ну в питоне мог быть уместнее и третий вариант метапрограмирование, или через декораторы или для более сложных случаев через метаклассы.
Здравствуйте, FR, Вы писали:
FR>>>В питоне также естественно. FR>>>ФВП полноценные плюс динамика и утиная типизация. FR>>>И кстати как раз в питоне можно совсем без наследования прожить. N>>Можно, не спорю. Но удобно ли? FR>Если пишешь в нужном стиле то вполне :)
Гм, и зачем мне сначала вырабатывать стиль, а затем подгонять под него решение кровью и рашпилем? По-моему, мы пока что не в Бангалоре.
N>>Не так давно добавлял одну функциональность к группе классов, прежде объединённых именно утиной типизацией (у них не было общего предка, были только одинаковые методы, но с заметно разной реализацией). Потребовалось добавить функциональность (асинхронная отработка вызова, причём с сериализацией адекватной задаче — несколько объектов фильтра могут использовать один прокси, но отрабатывать это должен тред, связанный с данным прокси). Оказалось, что надо писать почти один и тот же код (очень много общего) во всех классах фильтров. Вопрос — как это сделать?;)) Фактически получалось два варианта: FR>Ну в питоне мог быть уместнее и третий вариант метапрограмирование, или через декораторы или для более сложных случаев через метаклассы.
Метаклассы — для сильно уж сложных случаев, концепция сильно громоздкая (одно описание порядка поиска метода в документации способно поднять волосы дыбом у полностью лысого). Остальные — требуют по-любому больше писанины, чем одно легкочитаемое упоминание базового класса в заголовке определения.
Здравствуйте, McSeem2, Вы писали:
MS>Ну я уже говорил где-то. Это классический пример полиморфного поведения — перегрузка виртуальных функций. Это нормально, но это не наследование, это, дети, называется специализация. Что не нормально, так это расширение функциональности.
Так это не в наследовании проблема, а в его использовании. Если нарушать LSP, естественно добра от этого не жди. Классическая ситуация, описываемая присказкой про альтернативно одаренного человека и детородный орган из стекла.
Вообще, тут все намешали в одну кучу — наследование интерфейсов, наследование реализаций и LSP. В результате — каждый говорит о своем.
MS>Первенство по идиотизму до сих пор устойчиво держит фуфлоид под названием Венгерская Нотация.
Не отрывай труп, пусть покоится с миром.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111 on Windows Vista 6.0.6001.65536>>
Здравствуйте, samius, Вы писали:
S>То ли netch80 быстро меняет свою точку зрения, то ли не до конца ее излагает. S>netch80! S>Вы не хотите сформулировать свою позицию так, чтобы она не вызывала противоречий?
Здравствуйте, VoidEx, Вы писали:
Pzz>>Нет, это следует из подхода, за который вы агитируете. Который заключается в том, что знать надо только специфические для своей области вещи.
VE>Вы флеймер? Не надо нам приписывать слова, которых никто не говорил. VE>И таки ответьте на моё сообщение, ссылку на которое я давал 2 раза.
Нет, я не флеймер. В том сообщении, ссылку на которое вы давали, вы там с Нечаевым спорите на уже довольно громких тонах, если я ничего не путаю. Вот и продолжайте себе, мне в ваш спор встревать неохота.
Если у вас есть чего у меня спросить, не поленитесь повторить свой вопрос лично для меня.
Здравствуйте, netch80, Вы писали:
N>Гм, и зачем мне сначала вырабатывать стиль, а затем подгонять под него решение кровью и рашпилем? По-моему, мы пока что не в Бангалоре.
Угу писать на фортране можно используя любой язык
Просто начнешь всеръез писать используя функциональщину нужный стиль сам собой выработается и окажется что наследование для специализации малополезная вещь.
N>Метаклассы — для сильно уж сложных случаев, концепция сильно громоздкая (одно описание порядка поиска метода в документации способно поднять волосы дыбом у полностью лысого). Остальные — требуют по-любому больше писанины, чем одно легкочитаемое упоминание базового класса в заголовке определения.
Зато декораторы очень просто и легко, и как раз для всяких прокси и т. п. предназначены.
А так как миксин конечно и наследование нормально.
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, netch80, Вы писали:
N>>Гм, и зачем мне сначала вырабатывать стиль, а затем подгонять под него решение кровью и рашпилем? По-моему, мы пока что не в Бангалоре.
FR>Угу писать на фортране можно используя любой язык :)
Не любой. Арифметический IF не реализуется на языке без goto.
FR>Просто начнешь всеръез писать используя функциональщину нужный стиль сам собой выработается и окажется что наследование для специализации малополезная вещь.
Ну да, будем передавать вагон коллбэков. Так как всё-таки быть, если общего кода этак процентов 60? Ещё один вагон коллбэков?
N>>Метаклассы — для сильно уж сложных случаев, концепция сильно громоздкая (одно описание порядка поиска метода в документации способно поднять волосы дыбом у полностью лысого). Остальные — требуют по-любому больше писанины, чем одно легкочитаемое упоминание базового класса в заголовке определения. FR>Зато декораторы очень просто и легко, и как раз для всяких прокси и т. п. предназначены.
Вообще-то у меня словом "прокси" называлось совсем не то, что можно предположить исходя из контекста классов.:))
FR>>Угу писать на фортране можно используя любой язык
N>Не любой. Арифметический IF не реализуется на языке без goto.
switch, или таблица указателей на функции?
FR>>Просто начнешь всеръез писать используя функциональщину нужный стиль сам собой выработается и окажется что наследование для специализации малополезная вещь.
N>Ну да, будем передавать вагон коллбэков. Так как всё-таки быть, если общего кода этак процентов 60? Ещё один вагон коллбэков?
Угу, будем, только не коллбеков, а ФВП. И в этом стиле как раз обощаемость и повторное испрользование по моему повыще чем в ООП.
N>>>Метаклассы — для сильно уж сложных случаев, концепция сильно громоздкая (одно описание порядка поиска метода в документации способно поднять волосы дыбом у полностью лысого). Остальные — требуют по-любому больше писанины, чем одно легкочитаемое упоминание базового класса в заголовке определения. FR>>Зато декораторы очень просто и легко, и как раз для всяких прокси и т. п. предназначены.
N>Вообще-то у меня словом "прокси" называлось совсем не то, что можно предположить исходя из контекста классов.
Здравствуйте, Sinclair, Вы писали:
S>Вообще-то вопросы границ применимости встречаются постоянно. Простейший пример: парни проектируют систему миграции из инфраструктуры A в инфраструктуру B. Архитектурная идея — проста как грабли, и при этом хорошо идет в струе технологического совершенства: экспортируем все данные из A в XML, трансформируем его в понятный системе B XML при помощи XSLT, и радуемся жизни. S>И тут (через, грубо говоря, полгода разработки) вдруг возникает грустный эффект: трансформация подразумевает работу с DOM моделью, а далеко не все из интересных нам систем A генерируют документы, которые умещаются в 3GB RAM. Я доступно объясняю?
Испугал. Пишем для одной этой системы SAX трансформатор. Делов то
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, samius, Вы писали:
S>>Вы думаете, что я облажаюсь с пузырьком?
Pzz>А на квиксорте не облажаетесь?
Облажаюсь ли я на квиксорте?
Справлюсь ли я с поиском в ширину
Смогу ли перемножить матрицы
К счастью (моему), у меня и у моих работодателей вопросы интереснее. Чего и Вам желаю.
Не беспокойтесь, пока справляюсь.
З.Ы. Сортировку я возможно писал. Не отложилось в памяти. Не считаю это занимательным фактом, достойным биографии.
BSP дерево — писал. Ток не на интерес, а в рамках курсового. Задача курсового, кстати была не в том, чтобы написать BSP. И это я запомнил вовсе не потому, что написал BSP и офанарел от этого.
Здравствуйте, samius, Вы писали:
S>К счастью (моему), у меня и у моих работодателей вопросы интереснее. Чего и Вам желаю.
Вы не представляете, насколько они у меня интереснее
S>BSP дерево — писал. Ток не на интерес, а в рамках курсового. Задача курсового, кстати была не в том, чтобы написать BSP. И это я запомнил вовсе не потому, что написал BSP и офанарел от этого.
Интересная, кстати, структура. Я и не знал про такую, спасибо...
Здравствуйте, yumi, Вы писали:
N>>А на практике окажется, что из ~100 методов отличаются у потомков 20, и этого достаточно, чтобы действие "передать функцию поиска похожего блока" вылилось в извращение типа "передать структуру функций, специфичных именно для этой реализации". И всё это с костылями вроде приведения типов.
Y>Если на практике ~100 методов, то эту практику нужно прекращать немедленно Y>А костыли эти появляются из-за того, что языки не поддерживают higher-order functions & functions as first class objects.
А вот тут подробнее, пожалуйста. Как упомянутые фишки изменят дело, кроме более удобного синтаксиса?
Вот задачка: есть семейство алгоритмов (та же компенсация, допустим), которые теперь отличаются не одной функцией, а пятью (при этом имеют по 10 общих). В случае ООП и наследования все просто — общие функции в базовый класс, различные — в наследников.
А что в этом случае делают в Хаскеле и Лиспе?
Не передают же при каждом вызове "вагон колбеков", как тут его назвали.
Первое, приходящее мне на ум решение, — функция-конструктор, которая получает на вход охапку тех функций, что отличают конкретный алгоритм, и выдает в качестве результата одну функцию, его реализующую. Последняя уже вызывается когда надо. Т.е. все детали специализации пошли в замыкание, и по сути, мы получили некий аналог объекта из ООП, но с меньшим числом степеней свободы.
Здравствуйте, D. Mon, Вы писали:
DM>А вот тут подробнее, пожалуйста. Как упомянутые фишки изменят дело, кроме более удобного синтаксиса? DM>Вот задачка: есть семейство алгоритмов (та же компенсация, допустим), которые теперь отличаются не одной функцией, а пятью (при этом имеют по 10 общих). В случае ООП и наследования все просто — общие функции в базовый класс, различные — в наследников.
А у тебя тут не ожидается комбинаторного взрыва наследников?
DM>А что в этом случае делают в Хаскеле и Лиспе? DM>Не передают же при каждом вызове "вагон колбеков", как тут его назвали.
Нет конечно, они обычно осмысленно комбинируется в промежуточные сущности.
DM>Первое, приходящее мне на ум решение, — функция-конструктор, которая получает на вход охапку тех функций, что отличают конкретный алгоритм, и выдает в качестве результата одну функцию, его реализующую. Последняя уже вызывается когда надо. Т.е. все детали специализации пошли в замыкание, и по сути, мы получили некий аналог объекта из ООП, но с меньшим числом степеней свободы.
В общем да так и будет, только наоборот на объектах и будет корявое подобие с ограниченым числом степеней свободы
Здравствуйте, McSeem2, Вы писали:
MS>Слушай, Игорь, но почему именно "озабочусь иерархией классов"? Что, без наследования в современном мире не прожить? Лично я считаю парадигму наследования самым противоестественным самодурством какого-то одного горе-теоретика, типа авторитета, которому удалось запудрить мозги всем и надолго.
Проблемы обычно встречаются при наследовании реализации. А какие проблемы у наследования интерфейса? К тому же иерархия объектов — это не обязательно наследование.
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, netch80, Вы писали:
IT>>Нет таких алгоритмов, которые можно сделать на C и нельзя сделать на том же C# так же или проще. Обратное неверно. Возьми хотя бы замыкания.
N>Обратное верно, если учесть хотя бы низкоуровневую специфику,
Для низкоуровневой специфики лучше всего использовать ассемблер. Впрочем, C это и есть почти ассемблер, вот пусть он этими спецификами и занимается. А тягаться с высокоуровневой логикой на C даже не смешно.
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.