LINUX.ORG.RU

[philosophy] В чем заключается революционность перехода от функциональщины к ООП?


1

0

Так уж повелось, что первый язык, который я изучал, был делфи. Потом всякие сишарпики, С++, лисп, и т.п. В итоге, как мне кажется, у меня ООП головного мозга. Когда возникала задача писать на С, я начал реализовавывать обьектную модель в этом языке.

«Стоп», сказал я себе и подумал. Почему сейчас все кругом вопят про ООП и про его архиполезность и архиправильность? Далее, по ходу раздумий, пришел к мысли, что все, что пишется с использованием ООПшной парадигмы, может быть написано и без нее.

Почему появились языки, которые взяли ООП за главенствующую идею (java, c#, етц)?

Неужели те преимущества, которые предлагает ООП (полиморфизм, инкапсуляция, наследование), дают прирост в эффективности, скорости написания программ, понимания их работы и поддержке? Здесь было бы интересно сравнить одну и ту же программу, написанную на С и на С++, чтобы узреть принципиальные архитектурные различия (может такие уже есть?).

Сухой остаток. ООП представляет из себя еще один уровень абстракции, который позволяет оперировать про проектировании не функциями, а обьектами. А неужели это так меняет дело и делает разработку более удобной?

Было бы интересно без срачей услышать компетентное мнение.

★★
Ответ на: комментарий от Manhunt

Вообще, это я хотел, дополнив Miguel, намекнуть на убогость мейнстримного ООП, в котором методы внутри классов, т.е.

Love5an
()
Ответ на: комментарий от Miguel

Ты специально не хочешь различать активные и пассивные роли? Про страдательный залог в естественных языках слышал когда-нибудь?

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

>Я говорил про анализ и проектирование. А в твоей цитате речь идет о быдлокодинге. Видишь разницу между первым и вторым?

Проекты вне реализации имеют нулевую ценность, что делает затруднительным их оценку =)

Хотел ботву про деревья, ручки и естественность расписать для процедурного программирования(проектирование и анализ в рамках которого для мозга проще), но стало лениво.

F457 ★★★★
()
Ответ на: комментарий от DonkeyHot

> Ну, в общем, да - будь у нас 6 конечностей мы бы вряд ли встали на 2, а так - манипуляторов не хватало, вот и ходим.

В конечном итоге у тебя (лично у тебя) есть на выбор три варианта:
* таки перемещаться на двух ногах
* поручить работу по перемещению железяке
* перемещаться самому на четвереньках/ползком/вплавь, но как правило гораздо менее эффективно, чем в первых двух случаях

Вот и с анализом/проектиорванием так же:
* таки использовать ОО
* железяк еще придумано
* использовать другие подходы, эффективные лишь в довольно узких классах проблем

Ну а мечты о восьминогих людях-пауках и умственно-неограниченных функциональщиках - увы - остаются мечтами.

Manhunt ★★★★★
()
Ответ на: комментарий от oami

>Мне явно требуется усилитель мощности мышления. Пока этой мощности не хватает на объектную формализацию этических понятий. Добро и зло, честь и т.п.
Все эти типы при программировании формализуются в определённой предметной области. Например, если у нас есть персонаж в игре, мы можем задать ему такие характеристики. И тогда все методы и атрибуты сами вырисовываются.

Да и с математикой тоже не все ясно. Например, любое ли множество является объектом?


Любое. Если ты про бесконечное - сделай рекурсию.

anonymous
()
Ответ на: комментарий от linuxfan

>>> Не «функциональщина», а «императивщина». Дальнейшая дискуссия бессмысленна ввиду отсутствия у топикстартера владения терминами предметной области.

Что-то мосье плавает в терминологии предметной области.

То, что тов. linuxfan плавает в терминологии предметной области, я уже понял.

Во-первых, почитай хоть оригинальный пост и комменты. Топикстартер имел ввиду именно процедурщину.

Во-вторых, [ФП, ИП, ЛП] и [ПП, ООП и тд] - термины из разных множеств. Ocaml - объектно-ориентированный и при этом функциональный. Smalltalk - объектно-ориентированный и при этом императивный.

yoghurt ★★★★★
()
Ответ на: комментарий от dave

>Как минимум, пункт encourages в случае Си не работает.

А я считаю, что очень даже работает. Если чьи-то потные ладошки так и тянутся к сохранению состояния в глобальных переменных в тех случаях, когда этого делать не нужно, то это проблема исключительно обладателя потных ладошек, но никак не языка. Сам язык, напротив, хорош тем, что уж если надо прострелить ногу из пистолета, количество искусственных препятствий будет сведено к минимуму.

linuxfan
()
Ответ на: комментарий от F457

>на выборке 1 человек(ты сам) ты начинаешь глобальные выводы делать. смишно.

Ога, типа этот учитель-неудачник есть первый ООП-программист, что я вижу. Смишно.

anonymous
()
Ответ на: комментарий от F457

> Проекты вне реализации имеют нулевую ценность

Размести объявление с нормальным окладом на headhunter, желающие реализовать набегут толпами.

Хотел .. расписать .. но стало лениво.


Едва ли это можно назвать веским аргументом в пользу «процедурное программирование (проектирование и анализ в рамках которого для мозга проще)». Когда определишься, как ребенок из десткого сада должен представлять себе растущее во дворе дерево в терминах целочисленных и плавающих переменных и их массивов - возвращайся ;)

Manhunt ★★★★★
()
Ответ на: комментарий от Miguel

> aPaper writeOn: aText with: aPen

Бумага написать на текст? Да еще и с ручкой %)

aText beWrittenOn: aPaper with: aPen

beWrittenOn


Ну, это просто извращение

oh
()
Ответ на: комментарий от anonymous

Судя по тому, что о выборке из 1 человека, возражений не поступало, у тебя богатый опыт обучения людей))

Как бы этого не хотелось одептам ООП, сия идея ни разу не естественна для понимания и довольно сложна для изучения.

F457 ★★★★
()
Ответ на: комментарий от Love5an

намекнуть на убогость мейнстримного ООП

Не надо мне на неё намякивать, я и так в курсе.

в котором методы внутри классов

Да какая, в попу, разница, где методы. Всё одно ad-hoc полиморфизм, и только.

Собственно, я пока не видел системы типов, которая позволяла бы нормально разруливать подобные вещи, когда мультиметод определён для (A,X) и (B,Y), не определён для (A,Y), при этом любая попытка даже косвенно вызвать этот метод для (A,Y) приводила бы к ошибке в compile-time.

В традиционном ООП если что-то не определено, то это можно таки отдетектить при компиляции, в случае мультиметодов - хрен.

Miguel ★★★★★
()
Ответ на: комментарий от yoghurt

>То, что тов. linuxfan плавает в терминологии предметной области, я уже понял.

А тут что, обсуждают не парадигмы, а преимущества, которые дает синтаксис object->method(args) по сравнению с class_method(object,args)?

Ocaml - объектно-ориентированный и при этом функциональный

А, я понял: для тебя «объектно-ориентированный» тождественно «в языке есть ключевое слово class/object».

linuxfan
()
Ответ на: комментарий от SV0L0CH

>C++ можно рассматривать так язык с поддержкой ФП.

Напишешь на плюсах аналог лиспового #'mapcar? Пусть оно берет на вход функтор f от N аргументов и ещё N контейнеров c1...cN, и на выходе формирует контейнер заданного типа r, каждый элемент которого r[i] есть f(c1[i]....cN[i]). Для любого N.

yoghurt ★★★★★
()
Ответ на: комментарий от linuxfan

>А, я понял: для тебя «объектно-ориентированный» тождественно «в языке есть ключевое слово class/object».

Нет, заблуждаешьсо

yoghurt ★★★★★
()
Ответ на: комментарий от Manhunt

Ты специально не хочешь различать активные и пассивные роли? Про страдательный залог в естественных языках слышал когда-нибудь?

бог.подготовить(писатель.рука)
бог.подготовить(ручка)
бог.водить(бумага)

А ты специально не понимаешь, что означает «статические гарантии» и для чего они нужны? Специально не понимаешь, что твой подход с тремя вызовами функций более error-prone? Специально не понимаешь, что ты, фактически, эмулируешь ассемблер при помощи ООП?

PUSH ручка
PUSH бумага
PUSH текст
CALL писать

Miguel ★★★★★
()
Ответ на: комментарий от F457

>Как бы этого не хотелось одептам ООП, сия идея ни разу не естественна для понимания и довольно сложна для изучения.

Как бы ты ни пытался внушить эту глупость окружающим, сия затея обречена на провал.

anonymous
()
Ответ на: комментарий от yoghurt

По ссылке на википедию прошел, там как раз противопоставляется ООП (находится в группе императивные) и ФП. Хотя может быть linuxfan подредактировал :)

oh
()
Ответ на: комментарий от anonymous

Как бы ты ни пытался внушить эту глупость окружающим, сия затея обречена на провал.

Меня окружают сплошные идиоты...

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

Вот, не троллинга ради, а из-за интереса:
у меня есть какой-то объект с характеристиками, например, пользователь ЛОРа. Есть логин. Я хочу написать библиотеку для постинга на ЛОР. Если я строю все объектно, то получится что-то типа

мигель = новый пользователь(user => "Miguel");
мигель->новость(заголовок => "111", body => "blabla")
...
мигель->комментарий(к => 1234, текст => "...")

А без использования ООП, где мне держать параметр user лучше,

PS: наверное не самый лучший пример, но все-таки..

oh
()
Ответ на: комментарий от yoghurt

Напишешь на плюсах аналог лиспового #'mapcar?

Ну, вообще-то, написать, я думаю, вполне можно, даже с нуля.

Правда вот откомпилить это дело и распространять бинарник - таки фиг.

Miguel ★★★★★
()
Ответ на: комментарий от oh

>как раз противопоставляется ООП (находится в группе императивные) и ФП

Противопоставляются там декларативщина и императивщина.

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

Там подгруппа ООП находится в группе imperative, а ФП - в группе declarative.

oh
()
Ответ на: комментарий от Manhunt

>Размести объявление _с нормальным окладом_ на headhunter, желающие реализовать набегут толпами.

это очень хорошо показывает нулевую ценность идеи без реализации))

Едва ли это можно назвать веским аргументом в пользу «процедурное программирование (проектирование и анализ в рамках которого для мозга проще)». Когда определишься, как ребенок из десткого сада должен представлять себе растущее во дворе дерево в терминах целочисленных и плавающих переменных и их массивов - возвращайся ;)


Ну ты выше умудрился сие выдать за аргумент в пользу ООП...
А в реальной жизни нет у человека задачи «представлять себе растущее во дворе дерево», она не естественна для человека. Для человека естественна задача спилить дерево или посадить его... К необъектному подходу мозг тяготеет))

Если вспомнишь, то маленьким человекам объясняют программирование на основе «исполнителей»... робот там, чертежник... и могут мыслить в этих категориях гораздо больше людей, чем в категориях объектов(как практика показывает).

F457 ★★★★
()
Ответ на: комментарий от Miguel

Про сручку я пошутил, даже смайлик поставил!
Но «aPaper writeOn: aText » выглядит как-то не очень все-таки.

// PS: не фанат ООП

oh
()
Ответ на: комментарий от oh

Если я строю все объектно, то получится что-то типа

У меня только один вопрос: при чём тут объектность? Это же, фактически, сишный код:

#include "LOR.h"
LOR_user miguel = LOR_get_user("Miguel");
LOR_create_topic(miguel, "111", "blablabla");
Единственное что, в C неймспейсов нет, поэтому будут идиотские префиксы.

В .h-файле объявлено что-то вроде

struct LOR_user_impl {
  char* login;
};
typedef LOR_user_impl* LOR_user;

Здесь объектных плюшек нет вообще.

Miguel ★★★★★
()
Ответ на: комментарий от oh

Но «aPaper writeOn: aText » выглядит как-то не очень все-таки.

Как раз нормально, особенно, если aText - некая библиотечная штука, а aPaper - твоя собственная.

Miguel ★★★★★
()
Ответ на: комментарий от Love5an

Вообще, это я хотел, дополнив Miguel, намекнуть на убогость мейнстримного ООП, в котором методы внутри классов, т.е.

Дженерики отлично себя чувствуют и без ООП ;)

mv ★★★★★
()
Ответ на: комментарий от oh

Ну 'miguel' тебе придется за собой тащить везде, это не очень удобно.

Э-э-э... а в твоём варианте что, не придётся???

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

> если aText - некая библиотечная штука, а aPaper - твоя собственная.

А что это меняет? Какая разница, кто что написал? Ну, взяли мы aText из библиотеки, почему нельзя его написать на бумаге?
aText write: aPaper
?

oh
()
Ответ на: комментарий от yoghurt

>Напишешь на плюсах аналог лиспового #'mapcar?

Казалось бы, при чем тут ФП?

linuxfan
()
Ответ на: комментарий от oh

А что это меняет? Какая разница, кто что написал? Ну, взяли мы aText из библиотеки, почему нельзя его написать на бумаге?

Ну, автор библиотеки не предусмотрел.

Придётся извращаться, добавляя новый метод в класс, от которого у нас исходников нет.

Miguel ★★★★★
()
Ответ на: комментарий от oh

Нет, мы один раз «положили» в объект (экземляр) и забыли про него.

Кого положили? Чем твоя переменная «мигель» лучше моей переменной «miguel»?

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

Ну тогда надо переписать aPaper, чтоб она принемала aText и дальше вызывала aText writeOn

Хотя да, это извращение немного.

oh
()
Ответ на: комментарий от Miguel

Ну, смотри
1) А если у нас 100 таких переменных? Всех таскать и передавать как агрументы?
2) Получение user может быть очень сложной задачей, под которую реализован отдельный модуль, соответственно из других модулей этой переменной может быть не видно.

oh
()
Ответ на: комментарий от Miguel

> А ты специально не понимаешь, что означает «статические гарантии» и для чего они нужны?

Так мы скоро дороворимся, что результат работы программы нужно вычислять compile-time. А чо, статические гарантии :D

Специально не понимаешь, что твой подход с тремя вызовами функций более error-prone?


Мой подход моделирует реальный мир. Когда ты открываешь блокнот, затем берешь в руку ручку, затем начинаешь вырисовывать текст. После второго действия тебя могут на что-то отвлечь, и возможно ты какое-то время будешь бегать по комнате с блокнотом в руке. А потом бросишь его на тубмочку и выйдешь из квартиры, не написав не буквы.

Возможно, что такая детализация не нужна, и тогда действительно получается error-prone. Нужна или нет - никто не оговаривал.

Специально не понимаешь, что ты, фактически, эмулируешь ассемблер при помощи ООП?


До ассемблера мне дела нет, я думаю о предметной области.

Manhunt ★★★★★
()
Ответ на: комментарий от oh

Ты не там ищешь плюшки ООП. Они - в ad-hoc полиморфизме.

1) А если у нас 100 таких переменных? Всех таскать и передавать как агрументы?

Не понял, а ты сколько будешь таскать?

Получение user может быть очень сложной задачей, под которую реализован отдельный модуль, соответственно из других модулей этой переменной может быть не видно.

Ну и отлично.

Ещё раз: чем твоя переменная «мигель» лучше, чем моя переменная «miguel»?

Miguel ★★★★★
()
Ответ на: комментарий от linuxfan

Если чьи-то потные ладошки так и тянутся к сохранению состояния в глобальных переменных в тех случаях, когда этого делать не нужно, то это проблема исключительно обладателя потных ладошек, но никак не языка.

Не смешивай побочные эффекты и функциональность. Иногда одно другому не мешает. Язык Си располагает к написанию программ как последовательности пошаговых инструкций. Это не есть путь функционального программинга. Поэтому «it discorages.»

dave ★★★★★
()
Ответ на: комментарий от F457

> А в реальной жизни нет у человека задачи «представлять себе растущее во дворе дерево», она не естественна для человека. Для человека естественна задача спилить дерево или посадить его... К необъектному подходу мозг тяготеет))

Таки ребенку обясняют, что сейчас дерево - зеленое. А будет осень, и листва облетит. И еще дерево нужно поливать, а то оно засохнет. Состояния и методы, действие которых вляиет на состояние. Вполне понятны и естественны для человека в возрасте < 3 лет.

Если вспомнишь, то маленьким человекам объясняют программирование на основе «исполнителей»... робот там, чертежник...


Ты путаешь. Так пытаются объяснить концепции конечного автомата и машины тюринга. Без хотя бы смутного понимания которых быдлокодить не получится.

и могут мыслить в этих категориях гораздо больше людей, чем в категориях объектов(как практика показывает)


Они так мыслят о функционировании компьютера. А при анализе и проектировании компьютер тебя интересует в последнюю очередь. Интересует функционирование предметной области, с фон-нейманом как правило не связанной.

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

Так мы скоро дороворимся, что результат работы программы нужно вычислять compile-time.

Если результат работы никак не зависит от входных данных - да, разумеется. Только таких программ не бывает. Вообще.

Мой подход моделирует реальный мир.

Что никому нахрен не надо. Надо - писать быстро и по возможности безбажно. Ты же предлагаешь - медленно и без башни.

До ассемблера мне дела нет, я думаю о предметной области.

А тебе не известно, что то, КАК ты думаешь о предметной области, зависит от языка, который ты при этом используешь?

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

У меня «мигель» - это не переменная, а именно значение поля класса. Это более логично, ИМХО. Захочу - изменю на «oh», а тебе придется новую переменную заводить.
Или вот смотри, есть у что-то типа:

global loruser

proc post {
    loruser->новость(...)
    loruser->что-то(...)
}

proc init {
    loruser = new LORUser(user=>"miguel")
}

Я могу сделать

init
post
loruser->setName("oh")
post
А если ты в каждом вызове указываешь пользователя непосредственно, то придется выкручиваться заведением новых переменных и т.д., что может выглядеть коряво при большем наборе кода.

Ты не там ищешь плюшки ООП. Они - в ad-hoc полиморфизме.

В хаскелле же тоже есть спец. полиморфизм, вроде, нет?

oh
()
Ответ на: комментарий от Miguel

> А тебе не известно, что то, КАК ты думаешь о предметной области, зависит от языка, который ты при этом используешь?

Нередко язык выбирается уже _после_ того, как завершен анализ.

Мой подход моделирует реальный мир.


Что никому нахрен не надо. Надо - писать быстро и по возможности безбажно. Ты же предлагаешь - медленно и без башни.


Твоё высказывание никак не обосновано и не логично, одни только эмоции.

Если результат работы никак не зависит от входных данных - да, разумеется. Только таких программ не бывает. Вообще.


Ну так с чего тебе вдруг стало известно, что взятие карандаша, блокнота и написание текста - одно большой атомарное действие? С какого бодуна ты вдруг стал требовать тут compile-time проверок?

Manhunt ★★★★★
()
Ответ на: комментарий от oh

Захочу - изменю на «oh», а тебе придется новую переменную заводить.

Зачем? В C, вроде, никто не отменял сайд-эффекты (а было бы классное извращение).

LOR_user user;
void post() {
  LOR_create_topic(user, ...);
}
void init() {
  user = LOR_get_user("Miguel");
}
void change() {
  user = LOR_get_user("oh");
}

В хаскелле же тоже есть спец. полиморфизм, вроде, нет?

В Хаскеле есть всё.

В нём есть параметрический полиморфизм (повсюду).

В нём есть compile-time ad-hoc (классы типов) - которого, кстати, в тех же плюсах/жабе точно так же нету.

В нём есть runtime ad-hoc (замыкания).

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

>> Напишешь на плюсах аналог лиспового #'mapcar?

Ну, вообще-то, написать, я думаю, вполне можно, даже с нуля.

Правда вот откомпилить это дело и распространять бинарник - таки фиг.

Я хоть лисп не очень хорошо знаю, но подозреваю что это делал бы на шаблонах. И по-моему нечто подобное даже есть в STL.

SV0L0CH
()
Ответ на: комментарий от Manhunt

Твоё высказывание никак не обосновано и не логично, одни только эмоции.

Что именно не обосновано? Что надо писать быстро и безбажно? Требование бизнеса. Что твой подход медленнее? Сравни объём кода. Что твой подход более склонен к ошибкам? Ну, подумай, в какой момент обнаружится, что ты забыл подготовить бумажку (у меня - на стадии компиляции, у тебя - на стадии выполнения, а в случае более сложного кода - не первого выполнения). Что ещё обосновывать?

Ну так с чего тебе вдруг стало известно, что взятие карандаша, блокнота и написание текста - одно большой атомарное действие?

Сделал анализ предметной области.

Нередко язык выбирается уже _после_ того, как завершен анализ.

Если бы...

В этом случае немейнстримные качественные языки гораздо быстрее становились мейнстримом.

Miguel ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.