LINUX.ORG.RU

[вброс]Почему объектно-ориентированное программирование провалилось?

 


2

7

http://citforum.ru/gazeta/165/

по линку многабукаф, немного для Ъ:

факт остаётся фактом: сторона, представлявшая объектно-ориентированное программирование, во время открытой дискуссии с противниками под смех зала даже запуталась в своих же концепциях. Люди вспоминают, что у всех создалось стойкое впечатление, что аргументация Lisp’еров была куда убедительней и последовательней, чем сторонников ООП.

Другой крупный критик ООП – это известный специалист по программированию Александр Степанов, который, работая в Bell Labs, участвовал в создании C++ вместе c Бьерном Страуструпом (Bjarne Stroustrup), а впоследствии, уже после приглашения в HP Labs, написал Standard Template Library (STL). Александр Александрович полностью разочаровался в парадигме ООП; в частности, он пишет: “Я уверен, что парадигма ООП методологически неверна. Она начинает с построения классов. Это как если бы математики начинали бы с аксиом. Но реально никто не начинает с аксиом, все начинают с доказательств. Только когда найден набор подходящих доказательств, только тогда на этой основе выводится аксиома. Т.е. в математике вы заканчиваете аксиомой. Тоже самое и с программированием: сначала вы должны начинать развивать алгоритмы, и только в конце этой работы вы приходите к тому, что оказываетесь в состоянии сформулировать четкие и непротиворечивые интерфейсы. Именно из-за этой неразберихи в ООП так популярен рефакторинг – из-за ущербности парадигмы вы просто обречены на переписывание программы, уже в тот самый момент, когда только задумали её спроектировать в ООП-стиле”.

Ричард Столлман (Richard Stallman) также известен своим критическим отношением к ООП, особенно он любит шутить насчет того мифа объектников, что ООП “ускоряет разработку программ”: “Как только ты сказал слово «объект», можешь сразу забыть о модульности”.

Ричард Гэбриел неожиданно сравнивает нынешнюю ситуацию с ООП с провалом эфиродинамики в физике начала 20 века, когда, в сущности, произошла “тихая революция”.

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

>> Как минимум. в динамической типизации.

религия запрещает?

Ты не поймешь, даже если бы я стал объяснять. Вырастешь - может, сам поймешь. Хотя вон анонимный брат до сих пор хранит в списках void * и кастит по необходимости.

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

неявное преобразование типов в си гораздо опаснее чем динамическая типизация. В перле вон даже пофиг, число переменная содержит или строку, преобразуется по мере необходимости. Разве что производительность несколько страдает но тут проблема скорее в отсутствии оптимизирующих компиляторов

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

к чему угодно. В данном случае это стринг (не говоря то том, что стринг - это вообще всё что угодно):

typedef struct bucket{ char* key; void* data; struct bucket* next; } bucket;

struct hash{ long size; long n; long used; hash_bucket** table; char name[256]; };

struct hash* hash_create(long size); void* hash_put(struct hash* table, char* key, void* data); void* hash_get(struct hash* table, char* key); static unsigned long calc_hash(char* str); static int read_mapping(const char *filepath, struct hash *map);

int main(void){    struct hash* map; map=hash_create(100000); hash_put(map, «vasya», «пупкин»); printf(hash_get(map, «vasya»), %s); }

детали можете посмотреть в http://sourceforge.net/projects/aisconfig/

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

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

Полиморфные вызовы кода — нифига не главная задача ООП? Да это ключевое свойство, открывающее дорогу «отложенному» написанию и вызову нового кода в уже работающей программе.

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

нагляднее здесь: http://siberean.livejournal.com/2253.html

(ок, ок, плюсовский HashMap короче, но тормознее).

да мы и вообще не об этом. Джава вон тот-же динамический каст, к чему угодно.

Вы меня что - словить что-ли хотите? Я 20 лет хэшами с динамическим кастом пользуюсь и работает.

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

Ага, а статическая ява реализует генерики стиранием типов, проверяет типы коллекций в рантайме, позволяет как угодно кастить типы и пользоваться рефлекшеном. :)

Не нужно зеалотствовать. У статической типизации есть преимущества, но они лежат далеко за областью «проверки корректности» программ. И на такаом уровне дискуссия не имеет смысла.

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

>неявное преобразование типов в си гораздо опаснее чем динамическая типизация

Ты это программистам на Скале рассказывать будешь... ;) Там неявное преобразование позволяет писать относительно элегантые решения на базе чисто явских библиотек и/или делать eDSL'ы. Причем, все жестко типизировано, и контроллируется.

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

пусть и берут ООП те - кому надо что-то отложенное. Нам надо сейчас, конкретное (обычно - стринги, текст). Всё равно всё приходит как текст. Всё есть текст. Специальные валидации, да и вообще вся программа - это проверка типа.

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

> неявное преобразование типов в си гораздо опаснее чем динамическая типизация

Спасибо, что не оставляешь попыток просветить нас, нубов глупых.

tailgunner ★★★★★
()

Кстати, а почему на этот ООП-срач не пригласили Одерского?

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

> нагляднее здесь: http://siberean.livejournal.com/2253.html

Вот честно - мне почти безразлична производительность контейнера. И я уж тем более не собираюсь тратить время на его написание (пока это не станет _абсолютно_ необходимо).

Вы меня что - словить что-ли хотите?

Нет. Ты сказал интересные слова про области определения и значений, я попытался узнать подробности. Похоже, подробности сводятся к «обе области - строки или числа». Это неинтерсено.

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

> Ага, а статическая ява реализует генерики стиранием типов, проверяет типы коллекций в рантайме, позволяет как угодно кастить типы и пользоваться рефлекшеном. :)

И к чему ты это сказал?

Не нужно зеалотствовать.

«Не говорите нам, что делать, и мы не скажем вам, куда идти» (с)

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

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

А у тебя программа живых людей и бумажные деньги кушает, или всё же их модели в виде символов?

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

Блин, а мне казалась что Scala это попытка реализовать динамически типизируемый язык в пределах jvm. Хотя, признаюсь, язык и не видел а только слышал про него

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

> А у тебя программа живых людей и бумажные деньги кушает, или всё же их модели в виде символов?

И у этих символов есть типы. Причем несколько более сложные, чем строки и числа.

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

Ты путаешь с Groovy. В Scala, Одерский очень хорошо показал сочетаемость ООП и ФП подходов.

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

типы есть у всего, но типы - в твоей (и моей) голове.

Почему ограничиваешься одними типами и не рассматриваешь более крупные типы. Например, тип файла на входе. Или тип потока из базы данных. Если поток прервётся аварийно - мы же прерываем программу не крашем, а корректно. Т.е. я не вижу глобальной разницы в типе того Number в 10й колонке и миллионном рекорде и типом более крупного файла или набора контрольных таблиц, или наборов правил, итд.

Типы это абстракция и вся моя программа - это парсинг инпутов, анализ, валидация, трансформация и/или выплёвывания результатов. А какие я буду строить промежуточные деревья и какие лексеры-парсеры задействовать в чёрном ящике, какие AST строить и строить ли вообще и не ограничится ли иерархиями обычных хэшей хэшей - моё дело. Чтобы сделать мой оператор в кратчайший срок.

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

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

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

чтобы было ясно, конкретный пример: приходят заполненые индексы. Или номера машин. Есть такие типы в каком-то из языков? Конечно нет! Обычно есть примитивные числа и стринги. Номера - это типы. И их надо валидировать по конкретным правилам образования номеров (по госту, который каждые полгода меняется) и делать кросс-чек - что индексы соответствуют указанному адресу (городу). И скорее всего - даже геозапрос сделать. Только после подобных валидаций - можно сказать что номер и индекс правильные и соответствуют типам, а не просто стринги. Т.е. валидации подтвердили тип. В противном случае - мы бы скинули сообщение в нужную ячейку, скажем, базу данных.

Вся программа - это проверка типов вводов. И поток многих входных файлов - тоже тип. И процесс обработки - тоже тип. Итд. Т.е. имеем огромную машину с иерархией типов, имеющую _символы_ на входе из разных источников (даже если это пикселы с камер слежения - это тоже символы, так как они энкодятся base64 для передачи) и выплёвывающую символы или экраны или события - на выходе. Компьютеры - это обработчики символов, тюринговые машины.

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

>сущность с кучей аттрибутов

Что за сущность? Что за аттрибуты? Ты в своем предыдущем посте используешь понятие «тип» дай его определение.

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

> типы есть у всего, но типы - в твоей (и моей) голове.

Я не настолько доверяю своей голове, чтобы хранить в ней типы.

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

И ты об этом никому не расскажешь. Я понял.

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

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

я дал своё определение, как я это понимаю. tuple или множество аттрибутов, аксиом, артефактов, пришедших из окружения (т.е. которыми мы оперируем для программирования логики нашего оператора). Это простыми словами. В AI добавляют ещё поведение, т.е. скрипты и программы.

Поправьте - если знаете что неправильное определение (и в чём неправильно)

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

> И ты об этом никому не расскажешь. Я понял.

неправильно понял. Технические спецификации, документация и самое главное код - это описание.

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

А мне не нужно математическое опредленеие. Ибо иначе мы залезем в такие дебри мат. логики...

Я еще раз повторяю вопрос. В своем посте ты используешь понятие «тип». Что это по-твоему?

Я не собирась троллить или наезжать за точность или неточность определения. Мне просто нужно знать, чтобы понять твою точку зрения.

Пока все что ты говоришь — набор жутко перегруженных значениями слов.

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

> А с чего ты взял, что тип — непременный аттрибут языка программирования?

С того, что я не встречал языков, в которых не было бы типов.

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

>> И ты об этом никому не расскажешь. Я понял.

неправильно понял.

Тем не менее, пока что я прав. '

Технические спецификации, документация и самое главное код - это описание.

Слова, достойные DNA_Seq.

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

> Я не настолько доверяю своей голове, чтобы хранить в ней типы.

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

А стринг «ааааааааааааааааааааааааааааааааааааааааа» - это улица? 999999999999 - дом ли? 12345 - индекс?

Для валидации тебе дали документ который в 100 правилах описывает - что есть корректный индекс, против каких таблиц его проверить. И это будет зависеть от 4го поля, страны. Потому как в штатах это будет правильным индексом, а в Канаде - нет. И только после проверки/валидации - можно будет сказать - что запись (строка) - соответствует адресу (т.е. имеет тип адрес), а индекс - это реальный индекс.

Тип - это определение категории, а имя «индекс» - это всего лишь один из аттрибутов, которым мы наделяем слот данных.

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

> Я еще раз повторяю вопрос. В своем посте ты используешь понятие «тип». Что это по-твоему?

сказал же: набор (множество) аттрибутов. + набор операторов в виде программы и её грамматики (для полноты, чтобы ничего не забыть). Это если и behaviour учитывать.

я не силён в теории категорий, морфизмах.

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

>С того, что я не встречал языков, в которых не было бы типов.

А с чего ты взял, что нельзя определить типы, вообще никак не связанные с языком программирования?

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

>> Я не настолько доверяю своей голове, чтобы хранить в ней типы.

я тогда не понимаю - что ты понимаешь под типом.

Для Си++ - структура или класс.

Тип - это определение категории

Тип в языках программирования - это множество значений + множество операций над этими значениями.

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

> типы, вообще никак не связанные с языком программирования?

Ты ошибся топиком - здесь говорят о программировании. И типы здесь - те, которые есть в языках программирования.

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

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

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

А почему бы сразу не думать в терминах функции-оператора? А там (для минимализации сложности) - и объекты совсем другими будут. Может эффективно не адрес, а именно строки держать. Или 2 списка: валидные и невалидные индексы. Или вообще столбцы и их отношения across the files (локальная реляционка). Ведь это определяется алгоритмом - что надо сделать.

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

Вот смотри. В любой программе, на любом языке есть два фундаментальных типов комбинаторов (такой хрени, которая собирает кусок программы из кусков программы):

1. Комбинатор аппликации с типом (a -> b) -> a -> b
2. Комбинатор композиции с типом (a -> b) -> (b -> c) -> a - > c (специально написал именно так, чтобы не вностить путаницы).

Первый комбинатор берет функциональный тип f: a -> b и примитивный тип a, и конструирует f(a) c типом b.

Второй комбианатор берет два функциональных типа f: a -> b и g: b -> c и конструирует g(f) с типом a -> c (т.е. еще одну функцию).

Так вот, тип — это неявный параметр который передается тому или иному комбинатору. И задачей любого, даже самого расфуфыренного статического компилятора является мерзко орать: «Ах, выражение xxx суют выражение не того типа», в случае если программст облажался.

Т.е. в общем случае, компилятор позволяет контроллировать процесс сборки программы из «кусков». Все!

В этом смысле ТИП НЕ ЗАВИСИТ ОТ ДАННЫХ.

Но не все так плохо. Есть понятие зависимых типов, т.е. тип зависит от значения. Правда я не достиг такой степени просветления, чтобы понять механизм их действия.

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

т.е. я стараюсь мыслить в терминах процесса и динамики, что моя Тюринг-машина делает с окружением и как его меняет. Я не думаю в терминах объектов, и это мне помогает. Хотя бы тогда, когда поручают ответственный проект и мне и кому-то ещё, чтобы не завалить. И пару раз получалось, что чек делает через объекты, а потом оказывается, что на большой дате процесс идёт 2 дня. У меня отрабатывает за час. У него ещё и багов полно и он закопался. Хотя объекты какбы. А я знаю, что ничего лишнего я не нагродил, а добавлял объекты (и даже структуры, массивы) только по необходимости, и сильно быстрее это работать не может.

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

спасибо, посмотрю немного позже - надо бежать.

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

> А если не удобно запихивать сущность в один класс? Если сущность «размазана» по многим классам?

Ты же сам сказал «сущность» - значит, на каком-то уровне она едина. Что, конечно, не мешает ей быть набором связанных объектов.

Отношение (relation) - это тип?

Да, конечно.

А почему бы сразу не думать в терминах функции-оператора?

Вполне можно.

А там (для минимализации сложности) - и объекты совсем другими будут.

Но они же будут.

Ведь это определяется алгоритмом - что надо сделать.

Можно c тем же успехом считать, что это определяется спецификацией выходных данных.

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

>Ты ошибся топиком - здесь говорят о программировании. И типы здесь - те, которые есть в языках программирования.

Почему? Почему тип является аттрибутом языка программирования?

Почему я не могу написать статический (или динамический) анализатор, который не будет зависеть от компилятора или рантайма? Кстати, в эрланге так и сделано. А самый канонический пример - лисп.

Почему я не могу написать программу, которая в рантайме будет собирвать вполне себе статическую сущность по заданной спецификации? Канонический пример: собираем в рантайме POJO путем манипуляций с байт-кодом JVM.

Или сделать в динамическом языке типа руби, где типы не указываются явно, параноидальную проверку, которая будет анализировать метаданные объектов и являться частью юнит-тестирования?

Почему мы должны дрочить на то что нам предлагет язык программирования? Или спорить до хрипоты, какая парадигма лучше?

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

> Почему? Почему тип является аттрибутом языка программирования?

Потому что гладиолус. Тебе правда интересны настолько глубокие философские вопросы? Если да, то зачем?

Почему я не могу написать статический (или динамический) анализатор, который не будет зависеть от компилятора или рантайма? Кстати, в эрланге так и сделано.

Еще один странный вопрос. Откуда мне знать, почему ты не можешь? Другие же смогли.

Почему я не могу написать программу

Да откуда мне знать?

Почему мы должны дрочить на то что нам предлагет язык программирования?

А мы должны?

Или спорить до хрипоты, какая парадигма лучше?

А мы спорим?

P.S. Если хочешь что-то сказать - говори именно это. Прямо.

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

>Тебе правда интересны настолько глубокие философские вопросы? Если да, то зачем?

Да вот, эта дискуссия натолкнула. И вопрос не такой филосовский, как кажется.

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

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

> Тип в языках программирования - это множество значений + множество операций над этими значениями.

щас мне лень (хотя, конечно, надо) критиковать это определение, которое надо было выбросить на свалку еще на моем 1-м курсе

тут как минимум надо было сказать про инварианты или предикаты (хотя возможно они предполагаются в определении понятия «операция»)

например: тип это множество операций и предикатов над объектами типа; тут еще остается момент — добавление операций с предикатами можно считать не меняет тип... все это сложно; лично я пока не знаю хорошего определения типа данных хотя бы для с++

тип — это то, что позволяет делать вывод о поведении программы, оперирующей этим типом

вот например целое 4-х байтовое число, на которое есть 1. ровно одна ссылка снаружи 2. возможно более одной ссылки снаружи 3. не более одного указателя снаружи, причем к этому указателю разрешено применять арифметику указателей — это все разные типы данных (которые могут выражаться разными плюсовыми классами)

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

> это определение, которое надо было выбросить на свалку еще на моем 1-м курсе

Расслабься, ты не на лекции.

тут как минимум надо было сказать про инварианты или предикаты (хотя возможно они предполагаются в определении понятия «операция»)

Они предполагаются прежде всего в понятии «множество значений».

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

> Они предполагаются прежде всего в понятии «множество значений».

там они как раз и не особо интересны

а вот например class Item { Item* prev; Item* next; int payload; } с набором разумных операций будут вести себя совершенно по-разному в конфигурации кольца, восмерьки, кренделя (хотя бы потому, что крендель не может быть обойден ВЕСЬ через next-next-next...)

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

> а вот например class Item { Item* prev; Item* next; int payload; } с набором разумных операций будут вести себя совершенно по-разному в конфигурации кольца, восмерьки, кренделя

Класс (== один объект класса) - не будет; набор объектов класса - будет.

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

поправки:

1. prev в том определении лишнее

2. «крендель» название неподходящее, вот лучше картинка:

A->B->C
^     |
|     v
D<-E<-F<-G<-H<-I<-J
www_linux_org_ru ★★★★★
()
Ответ на: комментарий от tailgunner

> Класс (== один объект класса) - не будет; набор объектов класса - будет.

этот агрумент обламывается на примере с 1. одной и 2. многими ссылками на целое число

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

> Класс (== один объект класса) - не будет; набор объектов класса - будет.

Ну и вообще очень сомнительна ценность типов, когда они несут информацию о всего лишь 1 объекте; вот например мы, делая class Item { Item* prev; Item* next; int payload; }, предполагаем обычно что item_ptr->prev->next==item_ptr (в том случае, когда item_ptr->prev!=NULL), а тут участвуют уже 2 объекта или даже 3 объекта.

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