LINUX.ORG.RU

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


1

0

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

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

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

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

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

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

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

Придется в срочном порядке строгать костыли и ляпать заплатки на ставшую неконсистентной логику.

Отнюдь.

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

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

> Кстати, хочу напомнить на всякий случай, что undefined behaviour означает

Неверно. UB означает, что случилась полная ж0па, и программа запросто может вывалисться с сегфолтом или наглухо зависнуть, или даже сделать что-нибудь Совсем Плохое.

В случае f(g(),h()) имеет место unspecified behavior. iso/iec 9899:1999 раздел 3.4.4

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

Композиция — это то же перечисление последовательности действий, которое описывает «как делать», а не «что надо получить»

вообще-то, нет. композиция (и в общем построение сложных функций из простых) описывает чем делать, а не как. так STL повышает уровень декларативности за счёт перехода от явных циклов к конструированию функций с помощью ФВП (с композицией там не очень)

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

> Аккуратно разбить одну функцию на три вспомогательных - это тривиальный рефакторинг.

Тривиальным он будет, если на этапе анализа и проектирования честно и без преждевременных оптимизаций смоделировали предметную область. А не думали о том, каким бы хаком все поупрощать.

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

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

Уступают, смотря в какой области. Частично из-за того, что транзистор сам по себе уступает лампе (в определённой области).

Мы здесь про ООП или где?

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

И как тебе «ленивость» поможет в вычислении результата операции композиции?

прикинь, что res, x, y, z - векторы по 1000000 элементов. а теперь прикинь операцию:

res = x * y + 2 * z

что здесь произвойдёт со строго имеперативной точки зрения?

_i1 = x * y;
_i2 = 2 * z;
_i3 = _i1 + _i2;
res = _i3;

итого 2000000 операций умножения, 1000000 операций сложения и 4000000 операций присваивания. а если бы была ленивость, получилось бы что-то вроде:

_exp1 = mul(x, y);
_exp2 = mul(2, z);
_exp3 = sum(_exp1, _exp2);
res = force(_exp3);

сначала составили всё выражение, затем вычислили. итого 1000002 операции умножения, 1000001 операция сложения, 1000003 операции присваивания

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

А не думали о том, каким бы хаком все поупрощать.

Так не надо упрощать хаками.

Хак - это введение лишней сущности. Когда никому не надо.

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

>прикинь, что res, x, y, z - векторы по 1000000 элементов. а теперь прикинь операцию...

Правильный результатат «не скомпилируется». Напоминаю, что результат перемножения векторов — матрица.

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

>сначала составили всё выражение, затем вычислили. итого 1000002 операции умножения, 1000001 операция сложения, 1000003 операции присваивания

Какой ты, однако, теоретик. То есть, по-твоему, при вычислении res[i] = x[i]*y[i] + 2 * z[i] никаких промежуточных результатов не появляется (операций присваивания не происходит)? Ленивость не дает ровным счетом ничего кроме возможности создания операции ветвления средствами самого языка.

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

> при вычислении res[i] = x[i]*y[i] + 2 * z[i] никаких промежуточных результатов не появляется (операций присваивания не происходит)?

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

Afair, где-то у Страуструпа в главах про std::valarray упоминается возможность такой оптимизации.

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

> где-то у Страуструпа

«язык программирования с++ специальное издание», параграф 22.4.7

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

Ленивость не дает ровным счетом ничего кроме возможности создания операции ветвления средствами самого языка.

Это не так. Основная, на мой взгляд, плюшка ленивости - это техника «завязывания узла», когда структура данных определяется как результат применения некоей функции к ней же самой.

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

Напоминаю, что результат перемножения векторов — матрица.

векторное произведение в школе не проходили?

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

Afair, где-то у Страуструпа в главах про std::valarray упоминается возможность такой оптимизации.

и у Страуструпа, и у Джосаттиса. в обоих случаях ключевая техника оптимизации - ленивые вычисления

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

векторное произведение в школе не проходили?

Это ты зря сказал.

Результатом векторного произведения векторов из пространства $V$ является элемент пространства $\Lambda^2 V$, имеющего размерность $n(n-1)/2$.

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

Какой ты, однако, теоретик

какой ты, однако, упрямый идиот. ну сделай бенчмарк, померяй сам

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

Это ты зря сказал.

ок. рассматриваем покомпонентное произведение векторов A*B = [a1 * b1, .., an * bn]

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

> и у Страуструпа, и у Джосаттиса. в обоих случаях ключевая техника оптимизации - ленивые вычисления

Это не ленивые вычисления. Скорее уж глобальная оптимизация.

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

Это не ленивые вычисления. Скорее уж глобальная оптимизация.

почему это?

Потому что она вполне реализуется без ленивых вычислений (паттерн матчингом :)).

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

>Появляются, на регистрах процессора.

А это как оптимизатор положит. Регистров-то может и не хватить.

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

>векторное произведение в школе не проходили?

И скалярное тоже проходили. Только вот не вяжется как-то векторное произведение. которое в жизни чаще всего для нахождения нормалей используют, с размерностью пространства 1000000.

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

не вяжется как-то векторное произведение. которое в жизни чаще всего для нахождения нормалей используют, с размерностью пространства 1000000.

ну ок, не нравится мой маленький пример - посмотри на Blitz++. у них вся библиотека на expression templates по той же логике построена

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

Потому что она вполне реализуется без ленивых вычислений (паттерн матчингом :)).

не знаю как ты, а я тут вижу нормальный порядок вычислений - а если избавиться от повторного вычисления подвыражений, так вообще редукцию графов

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

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

не самый лучший пример, т.к. даже с чисто императивной точки зрения данная конструкция может быть легко улучшена до того же графа вычислений, что получится и при ленивых вычислениях. Так как при том же составлении выражения появляется overhead (в императивных языках мемоизацию не отменяли, так что повторный вызов за бонус не считается).

ИМХО бонус ленивости в том, что мы «из коробки» имеем возможность не вычислять то, что не надо, и как следствие легко работать с постоянными (persistent) структурами.

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

с чисто императивной точки зрения данная конструкция может быть легко улучшена до того же графа вычислений, что получится и при ленивых вычислениях

не понял, поясни

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

>у них вся библиотека на expression templates по той же логике построена

Зачем же так далеко ходить? В STLPort строковые операции на expression templates построены. Делают это ради минимизации накладных расходов на создание и копирование временных объектов.

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

В STLPort строковые операции на expression templates построены. Делают это ради минимизации накладных расходов на создание и копирование временных объектов.

ну вот тебе и ленивость. заметь, это не моё личное мнение:

http://en.wikibooks.org/wiki/More_C++_Idioms/Expression-template

The key idea behind expression templates is lazy evaluation of expressions.

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

в общем, в данном случае, я вообще не вижу разницы и причин почему ленивый вариант будет лучше и чем отличается вычисления графа:

    expr3(+)
   /       \  
 expr2(*)  expr1 (*)
 /  \      /  \
x   y     2    z

от приведённого императивного кода. Т.к. кол-во действий (в итоге) будет ровно одно и тоже, разве что можно догадаться не выделять лишние переменные под компоненты выражения, но ровно это же может сделать и любой компилятор =)

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

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

>The key idea behind expression templates is lazy evaluation of expressions.

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

Кстати, на практике это никакие не «ленивые вычисления», а построение графа вычислений. Чтобы убедиться в этом, достаточно глянуть в исходники. А уж как драматично этот трюк увеличивает время компиляции — это вообще отдельная песня.

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

>Надо быть дебилом(или троллем), чтобы не понимать(не признавать) причины, по которым CL не в мейнстриме.

«Как распознать идиота во время дискуссии»:

П1. Грубость и/или отсутсвие каких-либо обоснований фактических или логических при даче ответа или утверждении чего-либо

http://zhurnal.lib.ru/s/shapiro_m_a/raspidiota.shtml

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

Вообще говоря, «дискуссии» на ЛОРе состоят на 90% из троллей и дебилов(примерно поровну, бывает даже два в одном).

Специально для дебилов, которые не умеют пользоваться поиском, и не знают историю языков программирования и вычислительной техники хотя бы в общих чертах:
http://www.linux.org.ru/forum/development/4513948/page8#comment-4516776

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

Кстати, на практике это никакие не «ленивые вычисления», а построение графа вычислений

а что есть ленивые вычисления, как не редукция графа вычислений?

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

>Вообще говоря, «дискуссии» на ЛОРе состоят на 90% из троллей и дебилов(примерно поровну, бывает даже два в одном).

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

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

>Ты, похоже, как раз и есть это редкое сочетание.
Нет, я на тебя намекал.

культурному человеку

Я очень рад, что такой культурный(и грамотный - «драмматически») человек, как ты, сваливает, а то меня уже начало подташнивать.

За сим откланиваюсь.

Давай-давай, тут и так дебилов хватает.

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

>Кроме того, в силу непрерывно исходящей от тебя грубости и невежества >(типа «стуллмана»), культурному человеку будет попросту непритно с >тобой общаться. За сим откланиваюсь.

недооценивает обожаемый тобой сектантский идол

А по предмету обсуждения что-то высказать можете? Или сил хватает только на придирки к форме? Как насчет конкретных технических недостатков «сектантского идола»?

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

Как насчет конкретных технических недостатков «сектантского идола»?

Да, в общем, как обычно. Дисбаланс возможностей и ограничений в сторону возможностей. Жуткий дисбаланс.

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

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

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

Херня какая-то, бред, а не аргументы.

Для человека, пишущего в одиночку прототипчик программы - нормально. Для человека, пишущего не в одиночку, или пишущего библиотеку - неприемлимо, потому что другие пользователи (соотв. юзеры библиотеки) обязательно будут её абьюзить всеми способами, которые допускает язык


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


Btw.
Есть, кстати, мнение, что как-раз таки такие вот гибкие языки с динамической типизацией, как CL, лучше всего для крупных систем и подходят. Потому как в них проще отладка, ну и потому что развитие и все особенности функционирования крупных систем предсказать точно невозможно, а доработка и изменение таких систем в динамичных и гибких языках по понятным причинам проще чем в ...
А для мелкого прототипирования как раз лучше хаскель и подобные.

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

>а что есть ленивые вычисления, как не редукция графа вычислений?

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

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

>динамическая типизация

сложные системы

отладка проще

Три взаимоисключающих понятия в одном абзаце. Толстовато будет.

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

>А по предмету обсуждения что-то высказать можете?

Предмет обсуждения здесь - ООП, а не функциональщина. И зря Miguel начал кормить этого тролля.

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

Но, чтобы читающие не повелись на [троллинг] этого дебила, поясню немного:
динамическая типизация предполагает больший объем метаинформации в рантайме, чем статическая, и поэтому да, отладка при динамической типизации проще.

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

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

Ха! Так в том-то и дело, что не игнорирует. Но средств объяснить ему, как им следует пользоваться, в Лиспе почти что нет.

Ну, грубо: возьми тот же ассемблер, типа как манхунт предлагал:

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

В интерфейсе функции «написать» напрочь отсутсвует требование сделать сначала все три предыдущих действия. Поэтому рано или поздно, но в стеке окажется мусор.

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

А можно - сделать типизацию, и потребовать, чтобы первый аргумент был типа «то, чем пишут», второй - типа «то, на чём пишут», а третий - «то, что пишут». Будет ещё лучше.

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

Есть, кстати, мнение

Что колхозы постепенно вытеснят фермерские хозяйства. Знаем-знаем.

Потому как в них проще отладка

Во, о чём я и говорю. А на самом деле - не столько отладка должна быть проще, сколько отладки должно быть МЕНЬШЕ. Потому как она по определению процесс непроизводительный.

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

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

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

о, еще один дебил

Заигнорить тя, что ли.

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

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

http://en.wikipedia.org/wiki/Graph_reduction

хм?

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

И зря Miguel начал кормить этого тролля.

У меня троллеиндикатор очень хреново работает, вообще. Не знаешь, есть какие-то мастерские, где его исправляют?

Miguel ★★★★★
()

ООП нужно когда код пишется и поддерживается кучей народа, которой нужно быстро понимать, что написали другие (всякие БД и проч.). Наверное, поэтому ООП-языки и фреймворки поддерживатюся коммерчески - для них расширяемость намного важнее.

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

>Но средств объяснить ему, как им следует пользоваться, в Лиспе почти что нет.

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

Во, о чём я и говорю. А на самом деле - не столько отладка должна быть проще, сколько отладки должно быть МЕНЬШЕ. Потому как она по определению процесс непроизводительный.


Да, а еще охрененно было бы если бы ошибок вообще бы не было. Но этого не будет, потому что(и, соответственно, пока) программы пишут *люди*.
Ошибки и отладка - неотъемлемые части процесса разработки и использования программ.

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

А можно - сделать типизацию, и потребовать, чтобы первый аргумент был типа «то, чем пишут», второй - типа «то, на чём пишут», а третий - «то, что пишут». Будет ещё лучше.


Это такой тонкий намек? Я все никак не пойму, почему адепты статической типизации путают динамическую типизацию с отсутствием типизации вообще?

Что колхозы постепенно вытеснят фермерские хозяйства. Знаем-знаем.

Т.е. возражений нет?

В любом случае, мысль понятна: чем больше ограничений, тем большую надёжность можно обеспечить.

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

А чем больше возможностей - тем меньше способов наложить ограничения.

Это не так.

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

> динамическая типизация предполагает больший объем метаинформации в рантайме, чем статическая, и поэтому да, отладка при динамической типизации проще.

А ничё, что динамическая типизация принуждает на порядок больше времени тратить на отладку? Вся хвалёная производительность труда частенько вылетает в трубу из-за пары опечаток, которые компилятор отловил бы моментально. Я сам люблю динамические языки, но ты тут откровенно бредишь насчёт больших систем. Промышленная практика твои домыслы не подтверждает. Главная проблема динамики в том, что писать на ней нормально могут только люди с высокой квалификацией и самодисциплиной. Простого разгильдяя-погромиста даже близко нельзя к ней подпускать. А индустрия чуть менее чем полностью состоит из таких особей. Иначе будет просто убыточна.

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