Comments 137
Почему объектно-ориентированное программирование — это отстой.
А вот не подерётесь, а вот и не будет холивара.
А вот не подерётесь, а вот и не будет холивара.
А тут и не должно быть холивора. Это перевод статьи из достаточно далёкого прошлого.
Статья показывает спираль времени, и не более.
А ещё она показывает метастазы лор-синдрома на хабрахабре, где вместо чтения и обдумывания принято писать весёлые комментарии и плюсовать.
Статья показывает спираль времени, и не более.
А ещё она показывает метастазы лор-синдрома на хабрахабре, где вместо чтения и обдумывания принято писать весёлые комментарии и плюсовать.
Я не вижу смысла коментировать такие статьи с такими «кричащими» заголовками. Беглого прочтения мне достаточно. Да и смысл то, если я не согласен по всем четырём пунктам? Тут, как говорится, «кесарю кесарево».
>>лор
>>плюсовать
Ну ты понял. Плюсодрочерство присуще как-раз таки данному ресурсу.
>>плюсовать
Ну ты понял. Плюсодрочерство присуще как-раз таки данному ресурсу.
4 сомнительных доводов против, нет ничего идеального, и я использую ООП потому что доводов «за» куда больше четырех.
А такие доводы можно про все что угодно привести: «Функции отстой, когда появился ассемблер, там были лишь регистры и операторы, больше ничего не нужно, все открыто и понятно! поэтому я считаю что функции — отстой, они слишком группируют код»
Не поверите, но у меня отец примерно такого мнения. Он по образованию инженер-конструктор, ему схемотехника ближе и больше по душе. Поэтому программировать он может исключительно на ассемблере, а обо всём выше уровнем отзывается примерно так вот :)
Думать надо, а не пытаться думать, перед тем как что-либо делаешь. Если руки из сами знаете откуда, то самая лучшие инструменты не помогут.
ну как сказать.
ООП — это порядок. в принципе,
можно писать и на процедурах отличный код.
но ООП учить мыслить структурно, и заставляет тех, кто потом дописывает проект, перенимать образ мышления.
а тех, кто способен увидеть, что вы инкапсулируете реализацию, разделяете ответственности, в обычном хорошем коде на процедурах (или функциях в простом си), единицы.
да и потом, объект — хорошая абстракция, хороший инструмент. нужно уметь его готовить :)
ООП — это порядок. в принципе,
можно писать и на процедурах отличный код.
но ООП учить мыслить структурно, и заставляет тех, кто потом дописывает проект, перенимать образ мышления.
а тех, кто способен увидеть, что вы инкапсулируете реализацию, разделяете ответственности, в обычном хорошем коде на процедурах (или функциях в простом си), единицы.
да и потом, объект — хорошая абстракция, хороший инструмент. нужно уметь его готовить :)
Поддерживаю! ООП учит декомпозиции, учит уменьшению связности между кусками кода. Да, это не серебряная пуля, но плюсов у такого подхода очень и очень много. Помнится, был в универе у нас Пролог, так к концу семестра отлаживать программы, которые состояли из ~50 правил было уже почти невозможно. У каждого языка своя фича, так вот у Erlang — масштабируемость (эта та, которая меня прям сразила) за счёт функциональности языка. Это его вотчина, не надо туда лезть с ООП, «приделывать ООП к Prolog», ИМХО, глупо и бесполезно.
Понимаете, тут как. Структурное мышление, декомпозиция, системный подход — это всё межотраслевые дисциплины, которые ортогональны программированию (программированию вообще и ООП — в частности) в плане образа мышления.
И(П)П, ООП, ФП, ДП, ЛП — это всего лишь способ записи модели, построенной в голове у программиста.
Учиться структурному мышлению по конкретной парадигме — это как обучаться языку по политическим лозунгам, написанным на нём.
В этом плане статья очень показательна — автор критикует те моменты ООП, которые в нынешнем мире так или иначе выправлены средствами языков, которые поддерживают эту парадигму. Просто потому, что Симула, в которой эта парадигма реализовывалась, так сказать, в виде стандарта, тупо не взлетела. И Смолток, тоже, де-факто, не взлетел.
Тому есть обширный ряд причин со своими следствиями, но это надо обсуждать отдельно.
И(П)П, ООП, ФП, ДП, ЛП — это всего лишь способ записи модели, построенной в голове у программиста.
Учиться структурному мышлению по конкретной парадигме — это как обучаться языку по политическим лозунгам, написанным на нём.
В этом плане статья очень показательна — автор критикует те моменты ООП, которые в нынешнем мире так или иначе выправлены средствами языков, которые поддерживают эту парадигму. Просто потому, что Симула, в которой эта парадигма реализовывалась, так сказать, в виде стандарта, тупо не взлетела. И Смолток, тоже, де-факто, не взлетел.
Тому есть обширный ряд причин со своими следствиями, но это надо обсуждать отдельно.
По моим наблюдениям ООП моделирует предметную область от самого общего понятия объекта, постепенно конкретизируя. Как бы сверху вниз.
Но обобщать надо уметь правильно, так как неверное обобщение приводит к скрытым логическим ошибкам, когда глюк на высоком уровне влияет на большое количество нижних уровней
Но обобщать надо уметь правильно, так как неверное обобщение приводит к скрытым логическим ошибкам, когда глюк на высоком уровне влияет на большое количество нижних уровней
>а тех, кто способен увидеть, что вы инкапсулируете реализацию, разделяете ответственности, в обычном хорошем коде на процедурах (или функциях в простом си), единицы.
А можно пример, пожалуйста?
P.S. Не холивара ради. Для самообразования. Честно.
А можно пример, пожалуйста?
P.S. Не холивара ради. Для самообразования. Честно.
UFO just landed and posted this here
Так они и сейчас отстой. У них масса недостатков! Но это совсем не повод сейчас от них отказываться.
Электродвигатели вот по всем параметрам круче, но сколько там десятилетий прошло до тех пор, пока первый более менее успешный электромобиль сделали и сколько еще десятилетий пройдет прежде, чем они доминировать будут?
Всему свое время! Сейчас вот функциональные фишки тоже в мейнстримовые ЯП шагают.
Всему свое время! Сейчас вот функциональные фишки тоже в мейнстримовые ЯП шагают.
Электродвигатели далеко не по всем параметрам круче. Скорее даже наоборот: при равной мощности и долгоиграбельности (с учётом питания) они очень сильно проигрывают ДВСам по массе и габаритам.
Электродвигатели по всем показателям круче ДВС.
А вопрос питания — это не к двигателям претензии.
А вопрос питания — это не к двигателям претензии.
Теоретический подход.
Там, где вопрос питания ЭД не портит идею двигателя на корню, там, конечно, ЭД используются и в хвост и в гриву.
А там, где жёстко стоит вопрос питания, по совокупности пока что ведут ДВС и ТРД. А иногда даже самые тупые ЖРД!
Там, где вопрос питания ЭД не портит идею двигателя на корню, там, конечно, ЭД используются и в хвост и в гриву.
А там, где жёстко стоит вопрос питания, по совокупности пока что ведут ДВС и ТРД. А иногда даже самые тупые ЖРД!
В карьерных самосвалах как обстоит вопрос с питанием?
Я вас верно понимаю: вы спрашиваете как обстоят дела с питанием в повозке грузоподъёмностью 30-120 тонн?
Именно.
Хех. По каким параметрам ЭД лучше для повозок грузоподъёмностью 300-1000 кг?
Приёмистость. Высокий момент практически на любых оборотах. Отсутствие коробки передач и потерь энергии, связанных с ней.
Стало быть, вы в курсе и принципиальных недостатков ЭД? ;-)
По сравнению с ДВС это мелочи.
ЭД сам по себе отличный исполнительный механизм. Его слабое распространение связано исключительно с питанием, а не с его недостатками как двигателя.
ЭД сам по себе отличный исполнительный механизм. Его слабое распространение связано исключительно с питанием, а не с его недостатками как двигателя.
Так можно сказать про что угодно — например ДВС на водороде тоже очень хороши — мощные, экологически чистые, только вот такой объём водорода на дороге не валяется, но это не проблема движка, ага? :)))
Какой смысл рассматривать движок без питания? Он работает без питания? — нет! Следовательно и сравнивать нужно в комплексе!
Какой смысл рассматривать движок без питания? Он работает без питания? — нет! Следовательно и сравнивать нужно в комплексе!
Это сфероконь.
Вашими суждениями — гаубица вообще близка к идеальному механизму.
Даже так — фугас как таковой ещё лучше.
Человека в практической деятельности интересует энергетическая система в целом по параметру отношения технологических жертв к количеству производимой работы в единицу времени в разрезе разумно продолжительного времени.
По «разумно продолжительному времени» отсекается и ЭД, и гаубица, и фугас, и троллейбусы/трамваи, если разговор не идёт о карьерных самосвалах. И только.
Суда ходят на мазутных (дизель-газойльных) ДВС, к слову говоря. А грузоподъёмность ведь в десятки и сотни карьерных самосвалов.
Вашими суждениями — гаубица вообще близка к идеальному механизму.
Даже так — фугас как таковой ещё лучше.
Человека в практической деятельности интересует энергетическая система в целом по параметру отношения технологических жертв к количеству производимой работы в единицу времени в разрезе разумно продолжительного времени.
По «разумно продолжительному времени» отсекается и ЭД, и гаубица, и фугас, и троллейбусы/трамваи, если разговор не идёт о карьерных самосвалах. И только.
Суда ходят на мазутных (дизель-газойльных) ДВС, к слову говоря. А грузоподъёмность ведь в десятки и сотни карьерных самосвалов.
Caterpillar 797B грузоподъемность 345 тонн. Дизель.
Белазы и liebherr дизель-электрические, питание электроприводов обеспечивается как раз таки за счет ДВС.
Холиварить на тему ЭД vs ДВС можно долго, но пока нет достаточно эффективных аккумуляторов — ДВС будет лидировать. Ну или пока нефть не кончится.
Ну и еще один минус в сторону ЭД — пробой обмотки — довольно таки дорогостоящий ремонт выйдет.
Белазы и liebherr дизель-электрические, питание электроприводов обеспечивается как раз таки за счет ДВС.
Холиварить на тему ЭД vs ДВС можно долго, но пока нет достаточно эффективных аккумуляторов — ДВС будет лидировать. Ну или пока нефть не кончится.
Ну и еще один минус в сторону ЭД — пробой обмотки — довольно таки дорогостоящий ремонт выйдет.
«Реактивные двигатели делают и те и те, а цистерна топлива рядом, это уже не к двигателям претензии.»
Не убедили. Можно повторить все 4 пункта и сказать, что это достоинства.
Хотя я больше всего люблю Pascal…
Хотя я больше всего люблю Pascal…
> Поскольку функции и структуры данных — это совершенно разные виды животных, то решение содержать их в одной «клетке» фундаментально неверное.
Хммм, я б сказал, что функции — это животные, а структуры данных — это еда для животных, и в каждой клетке безусловно должна присутствовать пища, причём соответствующая. Не стоит кормить корову сырым мясом, а льва — сеном.
Хммм, я б сказал, что функции — это животные, а структуры данных — это еда для животных, и в каждой клетке безусловно должна присутствовать пища, причём соответствующая. Не стоит кормить корову сырым мясом, а льва — сеном.
Читал я оригинал по ссылке с хакерньюс. Не согласился.
Лично я как раз в процессе переписывания своего проекта, который был полностью сделан в процедурном стиле, на ООП.
Разрешите поделиться своими ощущениями.
Конечно, без базового образования крайне сложно перейти от процедурного мышления к ООП. Я очень долго пытался, читал книги и т.п. Но в какой-то момент пришло понимание.
И теперь я делаю проект практически заново, к старому обращаясь только как к справочнику — большая часть кода переписывается.
Зато — ощущение такое, что проект, сделанный по принципам ООП, более логичный и простой в понимании и изменении.
Я в одном месте поменял что-то, раз — и всё работает. И мне не надо держать в голове, или искать каждый раз, откуда какая процедура вызывается, какие там параметры в каком порядке, не надо данные из одной процедуры в другую пихать, и можно ли поменять что-то так, чтобы в другом месте не сломалось…
Преодолев определённый размер, процедурный проект стал лапшой, которую крайне сложно распутывать.
Собственно, ради этого и придумано ООП — части проекта мало связаны меж собой и их проще обновлять и изменять. И это главное преимущество ООП, как я его понимаю — а оно как раз в статье никак не опровергнуто.
Поэтому сейчас я за ООП. А недостатки можно везде найти — подумаешь, откровение какое. Попробуйте предложить что-нибудь другое.
Лично я как раз в процессе переписывания своего проекта, который был полностью сделан в процедурном стиле, на ООП.
Разрешите поделиться своими ощущениями.
Конечно, без базового образования крайне сложно перейти от процедурного мышления к ООП. Я очень долго пытался, читал книги и т.п. Но в какой-то момент пришло понимание.
И теперь я делаю проект практически заново, к старому обращаясь только как к справочнику — большая часть кода переписывается.
Зато — ощущение такое, что проект, сделанный по принципам ООП, более логичный и простой в понимании и изменении.
Я в одном месте поменял что-то, раз — и всё работает. И мне не надо держать в голове, или искать каждый раз, откуда какая процедура вызывается, какие там параметры в каком порядке, не надо данные из одной процедуры в другую пихать, и можно ли поменять что-то так, чтобы в другом месте не сломалось…
Преодолев определённый размер, процедурный проект стал лапшой, которую крайне сложно распутывать.
Собственно, ради этого и придумано ООП — части проекта мало связаны меж собой и их проще обновлять и изменять. И это главное преимущество ООП, как я его понимаю — а оно как раз в статье никак не опровергнуто.
Поэтому сейчас я за ООП. А недостатки можно везде найти — подумаешь, откровение какое. Попробуйте предложить что-нибудь другое.
>>Преодолев определённый размер, процедурный проект стал лапшой, которую крайне сложно распутывать
Т.е. по вашему процедурный код в любом случае станет лапшой, а ООП никогда лапшой не станет?
>>ради этого и придумано ООП — части проекта мало связаны меж собой и их проще обновлять и изменять.
Т.е. по вашему декомпозиция в процедурном стиле вообще не доступна?
Т.е. по вашему процедурный код в любом случае станет лапшой, а ООП никогда лапшой не станет?
>>ради этого и придумано ООП — части проекта мало связаны меж собой и их проще обновлять и изменять.
Т.е. по вашему декомпозиция в процедурном стиле вообще не доступна?
Я не знаю, почему вы обобщаете мои слова.
Я написал про свой проект и про свои ощущения от него.
Общих заявлений стараюсь не делать.
Я написал про свой проект и про свои ощущения от него.
Общих заявлений стараюсь не делать.
Лапша возможна и там и там.
Но для ООП существуют методики организации порядка (те же шаблоны проектирования), а для процедурного подхода ничего такого нет кроме интуиции программера.
Но для ООП существуют методики организации порядка (те же шаблоны проектирования), а для процедурного подхода ничего такого нет кроме интуиции программера.
Хорошо структурированный и написанный код везде хорош, как и в процедурном, так и в ООП.
Иногда я пишу ООП, иногда я пишу процедурами. Это все зависит от размера проекта и дальнейшего обслуживания.
Иногда я пишу ООП, иногда я пишу процедурами. Это все зависит от размера проекта и дальнейшего обслуживания.
вот только автор статьи противопоставляет ООП и функциональное программирование, а не процедурное ;)
С нетерпением жду, статей, продолжающих цикл: «Почему императивное программирование — отстой», «Почему функциональное программирование — отстой», и завершающей цикл статьи «Почему программирование — отстой».
Страуструп, типичные ошибки при разработке:
24.2.1. Отказ от классов.
24.2.2. Отказ от наследования.
24.2.3. Отказ от статической проверки типов.
24.2.4. Отказ от программирования.
24.2.5. Использование исключительно иерархий классов.
В статье многовато философии, по моему мнению. А философия плоха тем, что отворачивает взор от практики.
1е возражение — довольно спорно. Если юзается объект, значит у него есть некоторое внутреннее состояние. Внутреннее состояние (в виде структур данных) бесполезно, если оно никак не связано с внешним миром. А связано оно через методы. Так что получается, что структуры данных и функции для работы над ними не являются абсолютно разными вещами, а скорее частями одного целого.
С остальными аргументами более-менее согласен. Вообще приятно видеть, когда возражения против ООП адекватны, а не вытекают из непонимания концепций ООП спорящим (как на знаменитом избиении ООПшников на их же конференции).
1е возражение — довольно спорно. Если юзается объект, значит у него есть некоторое внутреннее состояние. Внутреннее состояние (в виде структур данных) бесполезно, если оно никак не связано с внешним миром. А связано оно через методы. Так что получается, что структуры данных и функции для работы над ними не являются абсолютно разными вещами, а скорее частями одного целого.
С остальными аргументами более-менее согласен. Вообще приятно видеть, когда возражения против ООП адекватны, а не вытекают из непонимания концепций ООП спорящим (как на знаменитом избиении ООПшников на их же конференции).
Тупой код и умные структуры данных проще в обслуживании и работают стабильнее чем умный код и тупые структуры данных. Пора уже с этим смириться.
Немного эмоционально, но в целом — по делу.
Автор гиперболизирует. Настоящая проблема в том, что универсальные языки — это отстой.
Каждый язык должен занять свою специализированную нишу и тогда будет порядок. То, что функциональные языки можно применять при сайтостроительстве, императивные при создании баз знаний, а логические при автоматизации процессов, как раз все это приводит к хаосу и вечным багам.
Каждый язык должен занять свою специализированную нишу и тогда будет порядок. То, что функциональные языки можно применять при сайтостроительстве, императивные при создании баз знаний, а логические при автоматизации процессов, как раз все это приводит к хаосу и вечным багам.
Уточните тогда: какие языки, на Ваш взгляд, наилучшим образом годятся для сайтостроения? И также ещё: какою, на Ваш взгляд, является ниша объектно-ориентированных языков?
>> какие языки, на Ваш взгляд, наилучшим образом годятся для сайтостроения
Это очевидно. Те языки, которые изначально для этого создавались (а не приросли библиотеками по мере эволюции). Тот же всеми любимый PHP.
>>И также ещё: какою, на Ваш взгляд, является ниша объектно-ориентированных языков?
Вопрос с подвохом. Ниша очень широкая, так как можно весь мир представить в качестве объектов наделенных методами и свойствами. Но если брать за примеры упомянутые мною сайтостроение и проектирование баз знаний, то писать рабочий код на С++ можно, но затратно по ресурсам — кроме денег уйдет просто банально много времени на «изобретение велосипедов», которые уже есть в специализированных языках.
Это очевидно. Те языки, которые изначально для этого создавались (а не приросли библиотеками по мере эволюции). Тот же всеми любимый PHP.
>>И также ещё: какою, на Ваш взгляд, является ниша объектно-ориентированных языков?
Вопрос с подвохом. Ниша очень широкая, так как можно весь мир представить в качестве объектов наделенных методами и свойствами. Но если брать за примеры упомянутые мною сайтостроение и проектирование баз знаний, то писать рабочий код на С++ можно, но затратно по ресурсам — кроме денег уйдет просто банально много времени на «изобретение велосипедов», которые уже есть в специализированных языках.
Автор однобоко подходит к виденью ООП. Дескать, «код и данные вместе», «состояния есть» и т.д. Достаточно чуть более глубоко взглянуть на процесс вызова метода класса, и мы увидим, что сам по себе этот метод никакого состояния не имеет — ему на вход неявно передаётся объект this и вот с этим объектом он все операции и делает. Вот вам и отдельно данные от методов. Не хотите иметь внутренних данных в классе с методами — ну, не создавайте их там. Делайте методы статическими. Храните данные в других структурах. Не храние их вообще нигде — вычисляйте на рантайме и гоняйте между статическими методами. Передавайте туда\сюда делегаты.
ООП даёт возможность быстрее и нагляднее моделировать реальный мир, не углубляясь в дебри логических построений. Это вот как измерить объём воды в стакане. Можно вывести через интегралы формулу объёма цилиндра, а можно взять мерную тару и перелить воду туда.
ООП даёт возможность быстрее и нагляднее моделировать реальный мир, не углубляясь в дебри логических построений. Это вот как измерить объём воды в стакане. Можно вывести через интегралы формулу объёма цилиндра, а можно взять мерную тару и перелить воду туда.
UFO just landed and posted this here
Каким объектам в реальном мире соответствуют фабрики, декораторы, визиторы?
первым двум — линейка сотовых телефонов, с одинаковой печатной платой внутри и разными наборами кнопок и функций.
У вас нарушение в логике.
Если «ООП даёт возможность быстрее и нагляднее моделировать реальный мир», то это ещё не означает, что «ООП может моделировать только реальный мир».
Если «ООП даёт возможность быстрее и нагляднее моделировать реальный мир», то это ещё не означает, что «ООП может моделировать только реальный мир».
Ничего подобного я не заявлял. И даже привёл обратные примеры.
Мысль в том, что не всё удаётся моделировать объектами один к одному, иногда приходится создавать «нереальные» объекты.
Мысль в том, что не всё удаётся моделировать объектами один к одному, иногда приходится создавать «нереальные» объекты.
Функциональные, процедурные и объектные языки — на любом из них, при желании, можно писать любой из парадигм. Но ООП превратить в функциональный или процедурный — проще.
UFO just landed and posted this here
Спор ниочем. ООП — это стиль. Смешивать стили программирования — это как заправлять шубу в трусы.
Посмотрите Nemerle, Ruby. В смешивании ничего плохого нет.
Вы же не станете утверждать что Ruby — это функциональный язык. Все базовые вещи там ООП.
Например, длина строки это метод str.length, в Erlang же функция — len(String).
Например, длина строки это метод str.length, в Erlang же функция — len(String).
Вместо того, чтобы приоткрыть состояние и минимизировать его влияние на код,
как раз состояние скрывают, чтобы минимизировать его влияние на код (чтобы состояние вручную не правили)
То, что ООП скрывает состояние — это только дает иллюзию того, что с большим и несвязанным состоянием можно как-то жить. Это только усугубляет проблемы, а не решает их.
Яркий пример — сложный UI с кучей событий, которые меняют свойства, которые в ответ на это стреляют еще события и т.п. Все моргает, добавление одного функционала ломает другой через какие-то хитрые взаимосвязи по состоянию; добавить высокоуровневые фичи типа сохранения состояния формы или undo — гигантская боль, т.к. способов работы с состоянием как с единым целым не имеется.
Яркий контр-пример — MVC в вебе, где вроде как ООП, а стейт — почти весь в базе и каких-то относительно простых и несвязанных между собой кэшах. Объекты если и мутируют, то только для того чтобы составить через это запрос на update в базе, а потом быть выкинутыми. Т.е. MVC — это подход в ФП-стиле. В противовес MVC можно посмотреть на ASP.NET webforms и оценить масштаб боли от ФП-подхода в той же самой задаче.
Яркий пример — сложный UI с кучей событий, которые меняют свойства, которые в ответ на это стреляют еще события и т.п. Все моргает, добавление одного функционала ломает другой через какие-то хитрые взаимосвязи по состоянию; добавить высокоуровневые фичи типа сохранения состояния формы или undo — гигантская боль, т.к. способов работы с состоянием как с единым целым не имеется.
Яркий контр-пример — MVC в вебе, где вроде как ООП, а стейт — почти весь в базе и каких-то относительно простых и несвязанных между собой кэшах. Объекты если и мутируют, то только для того чтобы составить через это запрос на update в базе, а потом быть выкинутыми. Т.е. MVC — это подход в ФП-стиле. В противовес MVC можно посмотреть на ASP.NET webforms и оценить масштаб боли от ФП-подхода в той же самой задаче.
Это не сложный UI, а кривой. Если не мешать всё в одну кучу, то ничего не моргает.
А на счёт состояния — MVC для этого и придумали, что бы путаницы не было. Правда, его мало кто реализует нормально.
А на счёт состояния — MVC для этого и придумали, что бы путаницы не было. Правда, его мало кто реализует нормально.
MVC нормально реализуют в вебе, потому что там мало внутреннего стейта и даже с ООП можно как-то более-менее отделить предметную область и функции над ней (модель), контроллер (монадические операции) и view — однонаправленные (в вебе) чистые функции из модели в html.
В дескопных приложениях это сделать трудно потому что классические ООП-языки плохо подходят для реализации своего же самого раскрученного паттерна. В десктопе ООП-библиотеки требуют копирования стейта в их объекты, через это требуется двунаправленная синхронизация этого стейта, которая почти всегда делается тупо руками. Есть датабиндинг, который упрощает это дело, и чем более он развит, тем более это все не ООП, а reactive programming, который гораздо больше уже про ФП.
В дескопных приложениях это сделать трудно потому что классические ООП-языки плохо подходят для реализации своего же самого раскрученного паттерна. В десктопе ООП-библиотеки требуют копирования стейта в их объекты, через это требуется двунаправленная синхронизация этого стейта, которая почти всегда делается тупо руками. Есть датабиндинг, который упрощает это дело, и чем более он развит, тем более это все не ООП, а reactive programming, который гораздо больше уже про ФП.
Яркий контр-пример — MVC в вебе
Пример некорректен. В вебе не приживаются stateful-подходы (тот же webforms), потому что сама по себе натура веба (http) — stateless. А вот в толстых клиентах подходы с состоянием как раз прекрасно работают (тот же WPF с его MVVM).
MVC — это подход в ФП-стиле
Это вы говорите сейчас про привычный нам всем mvc в вебе. А настоящий первый MVC — это вполне себе ООП.
Я специально разделил вебовский и обычный MVC, потому что это вообще две разные вещи.
Так вот вебовский прекрасно пашет из-за того что там размазанное ООП-приемами состояние не доживает до краха несогласованности.
А классический MVC, хоть и пытаются делать, нифига не получается. И чем дальше там уходят от ООП в сторону реактивного программирования (тот же WPF-ный датабиндинг) — тем всем становится легче. Это, конечно, обзывают свежепридуманными ООП-терминами, но это дорога в ФП-сторону.
Так вот вебовский прекрасно пашет из-за того что там размазанное ООП-приемами состояние не доживает до краха несогласованности.
А классический MVC, хоть и пытаются делать, нифига не получается. И чем дальше там уходят от ООП в сторону реактивного программирования (тот же WPF-ный датабиндинг) — тем всем становится легче. Это, конечно, обзывают свежепридуманными ООП-терминами, но это дорога в ФП-сторону.
Это, конечно, обзывают свежепридуманными ООП-терминами, но это дорога в ФП-сторону.
Я, если честно, с трудом понимаю, как модель с весьма существенным количеством внутреннего состояния (и перманентными побочными эффектами) можно называть движением в сторону функционального программирования.
В MVVM значимое состояние отделяют от всяких button.TextColor, а состояние UI привязывают декларативно к модели. Это движение в сторону более атомарного стейта, который сложнее рассинхронизовать, и всяких декларативных замутов, усложняющих отстреливание себе конечностей.
Если продолжить в этом направлении еще немного — получится чисто Functional Reactive Programming. Который обзовут как-нибудь типа «LINQ to DataBinding», скажут что сами это все придумали, и продолжат рассказывать какое ФП говно :)
Если продолжить в этом направлении еще немного — получится чисто Functional Reactive Programming. Который обзовут как-нибудь типа «LINQ to DataBinding», скажут что сами это все придумали, и продолжат рассказывать какое ФП говно :)
… а я все равно не понимаю, как вы можете говорить о чистом ФП при наличии побочных эффектов (и не просто состояния — а общего разделенного состояния).
А я не говорю о чистом ФП. Я говорю о переползании рожденных в ФП-сообществе подходов в мейнстрим.
Мой поинт в том, что люди говорят что ООП — это круто, тогда как все улучшения ООП-методологии с момента его изобретения заключаются в адаптации ФП-идей и послаблении всяких ООП-шных догм. Что хорошего придумали на основе прекрасной ООП-парадигмы за время ее существования?
Мой поинт в том, что люди говорят что ООП — это круто, тогда как все улучшения ООП-методологии с момента его изобретения заключаются в адаптации ФП-идей и послаблении всяких ООП-шных догм. Что хорошего придумали на основе прекрасной ООП-парадигмы за время ее существования?
Что хорошего придумали на основе прекрасной ООП-парадигмы за время ее существования?
Программирование на основе контрактов.
Роль контрактов в ФП выполняют развитые системы типов. Которые, кстати, реально работают и повсюду применяются.
А вот в ООП я за 7 лет промышленного программирования контракты не видел чтобы применялись.
А вот в ООП я за 7 лет промышленного программирования контракты не видел чтобы применялись.
Роль контрактов в ФП выполняют развитые системы типов.
И вот как развитая система типов определяет, какой набор операций может и должен совершать некий компонент?
А вот в ООП я за 7 лет промышленного программирования контракты не видел чтобы применялись.
Весь SOA, вообще-то. WSDL — это контракт. Даже интерфейс — это контракт.
Интерфейсы — это часть системы типов вообще-то. А wsdl описывает структуру данных, что тоже является частью системы типов.
Но в C# мы даже не можем на уровне системы типов сказать что параметр метода не может быть null. А в Хаскеле — можем. И можем даже написать имеет ли право функция делать IO. А в какой-нибудь AGDA мы даже можем сказать что функция не может возвращать не отсортированный список.
Да, многое чего не хватает системе типов в C#, можно проверить в рантайме. Чем и занимаются всякие контрактные библиотеки. Но это, очевидно, дает гораздо более слабые гарантии.
Но в C# мы даже не можем на уровне системы типов сказать что параметр метода не может быть null. А в Хаскеле — можем. И можем даже написать имеет ли право функция делать IO. А в какой-нибудь AGDA мы даже можем сказать что функция не может возвращать не отсортированный список.
Да, многое чего не хватает системе типов в C#, можно проверить в рантайме. Чем и занимаются всякие контрактные библиотеки. Но это, очевидно, дает гораздо более слабые гарантии.
Интерфейсы — это часть системы типов вообще-то.
И что, в системе типов ФП можно определять операции над типом?
А wsdl описывает структуру данных, что тоже является частью системы типов.
Э нет. WSDL описывает операции как раз.
Но в C# мы даже не можем на уровне системы типов сказать что параметр метода не может быть null.
Это недостаток языка, а не парадигмы. Что успешно доказано наличием большого количества статических анализаторов.
>И что, в системе типов ФП можно определять операции над типом?
Разумеется можно, нужно, и оно именно для этого и сделано.
>Это недостаток языка, а не парадигмы. Что успешно доказано наличием большого количества статических анализаторов.
Проблема в том, что в языке, в котором парадигма допускает неявные параметры и побочные эффекты, очень сложно давать сильные гарантии на уровне системы типов. У тебя нет возможности запретить читать и писать в статические переменные, нет возможности запретить ввод-вывод, нет возможностей запретить изменять переданные по ссылке параметры.
А в ФП это все явно, и через это просто. И в этом как раз одна из сильнейших сторон ФП. Пока люди, с переменным успехом, пытаются прикрутить хитрые статические анализаторы для обнаружения null-ов и т.п., в ФП языках оно уже есть из коробки и прекрасно пашет.
Разумеется можно, нужно, и оно именно для этого и сделано.
>Это недостаток языка, а не парадигмы. Что успешно доказано наличием большого количества статических анализаторов.
Проблема в том, что в языке, в котором парадигма допускает неявные параметры и побочные эффекты, очень сложно давать сильные гарантии на уровне системы типов. У тебя нет возможности запретить читать и писать в статические переменные, нет возможности запретить ввод-вывод, нет возможностей запретить изменять переданные по ссылке параметры.
А в ФП это все явно, и через это просто. И в этом как раз одна из сильнейших сторон ФП. Пока люди, с переменным успехом, пытаются прикрутить хитрые статические анализаторы для обнаружения null-ов и т.п., в ФП языках оно уже есть из коробки и прекрасно пашет.
Разумеется можно, нужно, и оно именно для этого и сделано.
Можете привести пример, как определить набор операций для конкретного компонента (т.е., не всех операций с типом, а только необходимых компоненту)?
Проблема в том, что в языке, в котором парадигма допускает неявные параметры и побочные эффекты, очень сложно давать сильные гарантии на уровне системы типов.
Повторяю еще раз: это проблема языка, а не парадигмы. И да, неявные параметры и побочные эффекты — это не объективные недостатки, а вещи, которые не рекомендуются в ФП. И в ФП вообще они прекрасно существуют (я знаю как минимум один язык, где это можно сделать).
Ну и да, например в WSDL можно указать, что передаваемый объект не может быть null.
>Можете привести пример, как определить набор операций для конкретного компонента (т.е., не всех операций с типом, а только необходимых компоненту)?
В Хаскеле это позволяют делать классы типов. В C# и Java — интерфейсы.
>Повторяю еще раз: это проблема языка, а не парадигмы.
Неявные параметры и сайд-эффекты прямо вытекают из императивной парадигмы. А их них уже вытекает сложность статического анализа кода и куча других проблем.
Идея ФП не в том, чтобы запретить стейт и побочные эффекты совсем. Без них ничего не сделать же. Идея в том, чтобы максимально локализовать их, и через это сделать предсказуемыми и управляемыми. Любая ФП-программа имеет императивный кусок, вопрос в его размере.
В Хаскеле это позволяют делать классы типов. В C# и Java — интерфейсы.
>Повторяю еще раз: это проблема языка, а не парадигмы.
Неявные параметры и сайд-эффекты прямо вытекают из императивной парадигмы. А их них уже вытекает сложность статического анализа кода и куча других проблем.
Идея ФП не в том, чтобы запретить стейт и побочные эффекты совсем. Без них ничего не сделать же. Идея в том, чтобы максимально локализовать их, и через это сделать предсказуемыми и управляемыми. Любая ФП-программа имеет императивный кусок, вопрос в его размере.
В Хаскеле это позволяют делать классы типов. В C# и Java — интерфейсы.
Как это делать в ООП-языках, я понимаю. А в ФП? Я бы хотел именно пример увидеть (в идеале, конечно, на F#).
F# я не шарю, но там вроде те же самые интерфейсы что и в остальном дотнете.
В Хаскеле похожая система:
есть тип:
data Person = { name :: String, age :: Integer }
есть классы типов (что-то вроде интерфейсов):
class Eq a where — класс типов, которые можно сравнивать на равенство
equals :: a -> a -> Bool
class (Eq a) => Ord a — класс типов, которые можно сравнивать на больше/меньше (от типа «наследует» Eq)
lessThan :: a -> a -> Bool
Мы можем реализовать Eq для Person:
instance Eq Person where
equals (Person name1 age1) (Person name2 age2) = (name1 == name2 && age1 == age2)
Дальше мы можем требовать в любых операциях, для любых операндов, принадлежность к одному или более классов типов:
printSorted :: (Ord a, Show a) => [a] -> IO() — чтобы напечатать сортированный список, надо его элементы уметь сравнивать и выводить в строку.
Это очень похоже на ООП-интерфейсы, но гибче.
В Хаскеле похожая система:
есть тип:
data Person = { name :: String, age :: Integer }
есть классы типов (что-то вроде интерфейсов):
class Eq a where — класс типов, которые можно сравнивать на равенство
equals :: a -> a -> Bool
class (Eq a) => Ord a — класс типов, которые можно сравнивать на больше/меньше (от типа «наследует» Eq)
lessThan :: a -> a -> Bool
Мы можем реализовать Eq для Person:
instance Eq Person where
equals (Person name1 age1) (Person name2 age2) = (name1 == name2 && age1 == age2)
Дальше мы можем требовать в любых операциях, для любых операндов, принадлежность к одному или более классов типов:
printSorted :: (Ord a, Show a) => [a] -> IO() — чтобы напечатать сортированный список, надо его элементы уметь сравнивать и выводить в строку.
Это очень похоже на ООП-интерфейсы, но гибче.
А теперь объясните мне, чем это не ООП.
А ты мне скажи определение ООП для начала. Так-то можно все к ООП свести.
Ну, так не интересно. Возьмем вики.
instance Person — сущность, ей можно послать сообщение equals с двумя параметрами и получить ответ. Данных у нее нет, но так бывает вообще.
Наследование есть, как мы видим на примере Eq и Ord.
Это, очевидно, тоже есть — может быть больше одного instance для одного класса Eq, и они могут иметь разную реализацию.
Так что формально это ООП, и от бытия ТРУ ООП его отделяет только наличие внутренних данных.
В центре ООП находится понятие объекта. Объект — это сущность, которой можно посылать сообщения, и которая может на них реагировать, используя свои данные.
instance Person — сущность, ей можно послать сообщение equals с двумя параметрами и получить ответ. Данных у нее нет, но так бывает вообще.
Наличие инкапсуляции достаточно для объектности языка программирования, но ещё не означает его объектной ориентированности — для этого требуется наличие наследования.
Наследование есть, как мы видим на примере Eq и Ord.
Но даже наличие инкапсуляции и наследования не делает язык программирования в полной мере объектным с точки зрения ООП. Основные преимущества ООП проявляются только в том случае, когда в языке программирования реализован полиморфизм; то есть возможность объектов с одинаковой спецификацией иметь различную реализацию.
Это, очевидно, тоже есть — может быть больше одного instance для одного класса Eq, и они могут иметь разную реализацию.
Так что формально это ООП, и от бытия ТРУ ООП его отделяет только наличие внутренних данных.
> Почему объектно-ориентированное программирование — это отстой?
А почему бы вместо того, чтоб 20 лет сотрясать воздух, не взять бы и не написать какую-нибудь вшвенькую 1С-бухгалтерию без объектов, зато на функциональном языке? Или игрушку какую в 3D?
Сразу бы все вопросы отпали, и у тех и у других :)
А почему бы вместо того, чтоб 20 лет сотрясать воздух, не взять бы и не написать какую-нибудь вшвенькую 1С-бухгалтерию без объектов, зато на функциональном языке? Или игрушку какую в 3D?
Сразу бы все вопросы отпали, и у тех и у других :)
Почему бы не построить безупречно и безотказно работающую телекоммуникационную платформу на императивном языке с ООП? :)
Наверное потому, что каждому инструменту — своё предназначение. В этом мире даже general-purpose-языки на поверку оказываются достаточно узко заточенными.
Ну и надо делать скидку на то, что те самые 20 лет назад стеки технологий были абсолютно другими, а ООП было на уровне концепций, местами сырых инструментов и нескольких фейлов типа современных Dart и Go.
Наверное потому, что каждому инструменту — своё предназначение. В этом мире даже general-purpose-языки на поверку оказываются достаточно узко заточенными.
Ну и надо делать скидку на то, что те самые 20 лет назад стеки технологий были абсолютно другими, а ООП было на уровне концепций, местами сырых инструментов и нескольких фейлов типа современных Dart и Go.
Игрушку? В 3D? На функциях? Да пожалуйста!
old.siteszone.ru/games.html
Все кроме последней 3Dшные написаны на Делфи-движке DGLE, который правда использует кое-где классы (вроде бы внутри него таки есть классы, но я то их не использую!). Пакмэн 3дшный тоже написан без классов.
Так что энто… уточняйте требования ;)
old.siteszone.ru/games.html
Все кроме последней 3Dшные написаны на Делфи-движке DGLE, который правда использует кое-где классы (вроде бы внутри него таки есть классы, но я то их не использую!). Пакмэн 3дшный тоже написан без классов.
Так что энто… уточняйте требования ;)
Где-то функциональный подход рулит (алгоритмы обработки потоковых данных к примеру, которые должны хорошо масштабироваться на N тредов и никакого состояния внутри особо не содержать). А есть сложные десктопные приложения, где состояние — это основное, и нужны какие-то абстракции, чтобы хранить это состояние. Не представляю себе WPF, реализованный в функциональном стиле. ООП просто сложнее приготовить правильно (зато проще сделать неправильно), это и приводит к тому, что библиотеки точатся и допиливаются годами, добиваясь смысловой целостности абстракций.
WPF во-первых весьма декларативен (XAML), во-вторых уже сильно ближе к ФП-стилю построения интерфейсов. Скажем развитый data binding — это движение в направлении reactive programming. А reactive programming — это как раз про то, как строить интерфейс в чистом ФП.
Или тот же MVVC-паттерн — это попытка выделить минимально возможное состояние и положить одним куском, не размазывая по коду, что тоже весьма в ФП-духе.
Просто ООП-шники все переназывают своими терминами, через это создается видимость что это ООП развивается и прекрасен. На деле все последние удачные движухи по поводу ООП-архитектур — это в основном перенятие кусочков ФП в ООП-мир.
Или тот же MVVC-паттерн — это попытка выделить минимально возможное состояние и положить одним куском, не размазывая по коду, что тоже весьма в ФП-духе.
Просто ООП-шники все переназывают своими терминами, через это создается видимость что это ООП развивается и прекрасен. На деле все последние удачные движухи по поводу ООП-архитектур — это в основном перенятие кусочков ФП в ООП-мир.
Что ж в этом плохого? Как раз за гибридными вещами будущее и есть. Никто не будет писать десктопные приложения на чистом функциональном языке. Программистам хочется делать не только функциональные абстракции, но еще и абстракции объектов, хранящих состояние. А уж чего больше в MVC и databinding'ах — ООП или функциональщины — это еще вопрос :) Реактивное программирование, судя по вики, к функциональному программированию не относится и является обособленной парадигмой, которую использует и ООП, и ФП. Выделение минимально необходимого это не есть изобретение ФП, это перифраз бритвы Оккама, методологического принципа, используемого повсеместно.
Ничего плохого нет.
Я бы даже сказал бы что термин «ООП-программирование» сейчас понимается больше как «прагматичный подход», а «ФП-программирование» — это больше даже не про ФП, это больше фронт научной мысли о программировании.
Новые интересные идеи в основном рождаются и оттачиваются во втором, а потом те, которые себя хорошо зарекомендовали переползают в «ООП-мир», где бережно и с поправкой на реальный мир реализуются.
Рано или поздно какой-нибудь опопсенный хаскель придет даже в enterprise-программирование, но промышленному программированию все равно придется пройти этот путь через гибридные языки.
Я бы даже сказал бы что термин «ООП-программирование» сейчас понимается больше как «прагматичный подход», а «ФП-программирование» — это больше даже не про ФП, это больше фронт научной мысли о программировании.
Новые интересные идеи в основном рождаются и оттачиваются во втором, а потом те, которые себя хорошо зарекомендовали переползают в «ООП-мир», где бережно и с поправкой на реальный мир реализуются.
Рано или поздно какой-нибудь опопсенный хаскель придет даже в enterprise-программирование, но промышленному программированию все равно придется пройти этот путь через гибридные языки.
ООП — не отстой, но и не панацея. ООП — всего лишь способ создания и разделения абстракций. Главные понятия — классы и объекты. Классы бывают двух видов: тип данных и средства обработки/модификации. Объекты — это экземпляры типов данных. ООП — идея о том, что можно написать код и использовать в дальнейшем. Но все учесть невозможно, поэтому и есть скрытое состояние объекта — чтобы программист не мог случайно поломать класс.
Эту тему лучше переименуйте так: Почему такие темы на хабре — это отстой?
Потому что 95% пользователей хабрахабра не знают Эрланг и, соответственно, не понимают, что имеет в виду товарищ Армстронг, говоря про описание типов, например.
Потому что 70% пользователей хабрахабра про ФП знают только, что «ну, там есть функции, монады и какое-то каррирование».
Потому что 50% пользователей хабрахабра находятся в состоянии аффекта под воздействием хайпа и всяких баззвордов с серебряными пулями.
Потому что 70% пользователей хабрахабра про ФП знают только, что «ну, там есть функции, монады и какое-то каррирование».
Потому что 50% пользователей хабрахабра находятся в состоянии аффекта под воздействием хайпа и всяких баззвордов с серебряными пулями.
> Мы придумали несколько достаточно нетривиальных ответов, которые бы представляли Erlang типа-объектно-ориентированным языком (для тех, кто больше всего тянет руку с этим вопросом), но при этом и не объектно-ориентированным для тех, кто на самом деле в теме.
При этом те, кто НА САМОМ ДЕЛЕ в теме, прекрасно понимают, что Эрланг — язык именно что объектно-ориентированный.
При этом те, кто НА САМОМ ДЕЛЕ в теме, прекрасно понимают, что Эрланг — язык именно что объектно-ориентированный.
Эрланг использует свой своебразный ООП только на крупном масштабе, а на мелком он чисто ФП-язык. Такой подход неплохо показывает себя.
Вообще ООП — неплохая парадигма для архитектуры приложения в крупном масштабе.
Есть и другие подходы, когда на крупном масштабе применяются монады, data-flow, reactive programming, message bus-ы, какие-нибудь DSL или еще что-то. Тут на вкус и цвет.
В ФП это либо эмулируется прямо в ФП-стиле, либо встраивается в язык. Но так или иначе в любой крупной функциональной программе что-то такое есть — на чистом ФП же нельзя сделать сколько-нибудь сложное приложение.
Вопрос тут только в том, от чего начинать плясать.
На мелком же масштабе ООП подталкивает плодить кучу ненужных сущностей, и кучу несвязанного, зачастую некогерентного стейта, а это хреново.
Вообще ООП — неплохая парадигма для архитектуры приложения в крупном масштабе.
Есть и другие подходы, когда на крупном масштабе применяются монады, data-flow, reactive programming, message bus-ы, какие-нибудь DSL или еще что-то. Тут на вкус и цвет.
В ФП это либо эмулируется прямо в ФП-стиле, либо встраивается в язык. Но так или иначе в любой крупной функциональной программе что-то такое есть — на чистом ФП же нельзя сделать сколько-нибудь сложное приложение.
Вопрос тут только в том, от чего начинать плясать.
На мелком же масштабе ООП подталкивает плодить кучу ненужных сущностей, и кучу несвязанного, зачастую некогерентного стейта, а это хреново.
> Эрланг использует свой своебразный ООП только на крупном масштабе, а на мелком он чисто ФП-язык.
Согласен.
> на чистом ФП же нельзя сделать сколько-нибудь сложное приложение.
Не согласен.
Согласен.
> на чистом ФП же нельзя сделать сколько-нибудь сложное приложение.
Не согласен.
На ФП все так или иначе себе стейт, монады, ООП, dataflow, и т.п. Называть ли это чистым ООП потому что оно сделано на чистом ООП — вопрос риторический.
>> на чистом ФП же нельзя сделать сколько-нибудь сложное приложение.
> Не согласен.
Чистый ФП == отсутствие побочных эффектов вообще. В частности, I/O на идеальном чистом ФП уже невозможно.
> Не согласен.
Чистый ФП == отсутствие побочных эффектов вообще. В частности, I/O на идеальном чистом ФП уже невозможно.
Алан Кей не заслужил, чтобы его изобретение называли отстоем.
Извинитесь сейчас же!
Извинитесь сейчас же!
У меня создалось впечатление, что автор статьи программировал в основном разнообразные вычисления и расчёты, где вся мощь ООП действительно не нужна.
Мне кажется, автор не программировал сколь-нибудь сложных структур данных. Красно-черное дерево это структура или функции, которые заставляют его делать свою работу и не нарушать целостность?
Какая невнимательность, вообще то статью написал создатель языка эрланг, глупо выглядите.
Был неправ, пропустил абзац об авторе.
Впрочем автор эрланга и статьи выглядит не менее глупо, так что на сей счет я не слишком переживаю.
Есть подозрение, что в некоторых пунктах (например в пункте про объявления типов и про популярность ООП) он говорит ООП, а имеет ввиду Java. Кто ж виноват, что не все реализации ООП прекрасны во всех отношениях? Но в конечном счете, джава не единственный ООП-язык.
Кстати, могли бы сказать что-нибудь и по сути. Разделение структуры данных и функций с ним работающих имеет какие-то «бонусы» кроме уязвимости целостности данных?
Впрочем автор эрланга и статьи выглядит не менее глупо, так что на сей счет я не слишком переживаю.
Есть подозрение, что в некоторых пунктах (например в пункте про объявления типов и про популярность ООП) он говорит ООП, а имеет ввиду Java. Кто ж виноват, что не все реализации ООП прекрасны во всех отношениях? Но в конечном счете, джава не единственный ООП-язык.
Кстати, могли бы сказать что-нибудь и по сути. Разделение структуры данных и функций с ним работающих имеет какие-то «бонусы» кроме уязвимости целостности данных?
Я правильно понимаю, что в пункте 2 abstime=2012 02 31 24 60 60 является валидной датой?
А -то думаю, что меня в сон клонит, когда работаю с объектами! :) Спасибо за статью.
Sign up to leave a comment.
Почему объектно-ориентированное программирование — это отстой