Функциональное программирование против ООП [закрыто]

93

В последнее время я много слышал об использовании функциональных языков, таких как Haskell. Каковы некоторые из больших отличий, плюсов и минусов функционального программирования от объектно-ориентированного программирования?

GSto
источник
27
Один не отвергает другого.
МБк
1
@mbq Я понимаю, что они не являются взаимоисключающими, но я просто хотел попытаться лучше понять разницу между этими двумя подходами.
GSto
Отличный вопрос Мне тоже было интересно об этом.
JohnFx
Функциональное программирование и объектно-ориентированное программирование ортогональны друг другу. Вы можете иметь оба на одном языке. Примеры: Scala, F #, OCaml и т. Д. Может быть, вы имели в виду функциональность против императива, как предложил Джонас ?
фактор
4
Реальный ответ - между ними нет "против". Проверьте этот вопрос в StackOverflow .
фактор

Ответы:

67

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

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

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

Императивный псевдокод для функции для вычисления суммы списка (сумма сохраняется в переменной):

int sumList(List<int> list) {
    int sum = 0;
    for(int n = 0; n < list.size(); n++) {
        sum = sum + list.get(n);
    }

    return sum;
}

Функциональный псевдокод для той же функции (сумма передается как параметр):

fun sumList([], sum) = sum
 |  sumList(v::lst, sum) = sumList(lst, v+sum)

Я рекомендую презентацию « Укрощение эффектов с помощью функционального программирования » Саймона Пейтона-Джонса для хорошего знакомства с функциональными концепциями.

Jonas
источник
12
Следует отметить, что функциональная версия является рекурсивной и поэтому оптимизирована, чтобы избежать переполнения стека. (Некоторые люди могут увидеть рекурсию и подумать, что из-за этого плохое функциональное программирование)
альтернатива
3
+1 для описания наиболее важного аспекта императива против функциональности: поток управления против потока данных. Я должен добавить, что функциональная парадигма и ОО-парадигма не являются взаимоисключающими; Вы можете использовать ОО-парадигму для моделирования взаимодействия объекта (данных) и функциональную парадигму для преобразования (манипулирования) этого объекта.
Ли Райан
1
Интересно, что вы можете моделировать данные как контроль и контроль как данные, а также смешивать их. FP может использовать стрелки и функции первого порядка, чтобы передавать поток управления и манипулировать им как данными. ООП использует различные шаблоны проектирования, чтобы использовать объекты для изменения потока управления.
CodexArcanum
Я также думаю, что стоит отметить, что главное отличие состоит не в том, что вы пишете одну и ту же программу, а выполняете циклически-рекурсивные вызовы методов. это намного больше, чем это
Сара
Ваш функциональный пример использует параметр сопоставления с образцом. Это не только функциональное программирование, аналогично функциональные программы могут использовать монады и даже императивные конструкции без необходимости формулировать каждый итерационный алгоритм как рекурсивный алгоритм.
Дай
16

Функциональное программирование основано на декларативной модели и основано на лямбда-исчислении. Он предлагает множество отличных концепций, которые можно позаимствовать из более важных языков, таких как C ++ и C #.

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

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

Для начала вы можете использовать чисто функциональный язык, такой как Haskell, или гибридный, такой как F # .

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


Каковы некоторые из больших отличий, плюсов и минусов функционального программирования от объектно-ориентированного программирования?

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

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

Брайан Р. Бонди
источник
2
Чтобы было ясно, Scheme ни в коем случае не является чисто функциональным языком.
Джонатан Стерлинг
5
Ваш второй последний абзац полностью бс. ОО не создает никаких проблем в многопоточности, изменчивость делает. Вы, кажется, путаете императивное программирование с объектно-ориентированным программированием. Это тот случай?
фактор
5
@missingfaktor: Нет, я не путаю понятия. Объект обычно имеет методы доступа, модификаторы, элементы данных и функции-члены. Да, не все объекты должны иметь модификаторы, и вы можете реализовать их как неизменяемые. Но если вы посмотрите на любую произвольную ОО-программу, она почти наверняка будет иметь несколько объектов, которые имеют модификаторы и все же используются многопоточностью. Т.е. в ООП-парадигме довольно редко иметь все неизменное.
Брайан Р. Бонди
Вы должны прочитать ответы на этот вопрос: stackoverflow.com/questions/3949618/fp-and-oo-orthogonal/…
missingfaktor
Также проверьте ответ Фрэнка Шиарара здесь: programmers.stackexchange.com/questions/12423/…
missingfaktor
8

(Этот ответ адаптирован из ответа на закрытый вопрос в StackOverflow .)

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

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

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

Когда эволюция идет не так, у вас есть проблемы:

  • Добавление новой операции в объектно-ориентированную программу может потребовать редактирования многих определений классов для добавления нового метода.

  • Добавление нового вида вещи в функциональную программу может потребовать редактирования многих определений функций для добавления нового случая.

Эта проблема была хорошо известна в течение многих лет; в 1998 году Фил Вадлер назвал это «проблемой самовыражения» . Хотя некоторые исследователи считают, что проблему выражения можно решить с помощью таких языковых функций, как миксины, широко распространенное решение еще не достигло широкого распространения.

Норман Рэмси
источник
Мне нравится ваш ответ, слово мудрости здесь. Я встретил его несколько месяцев назад и просто потратил 30 минут на его поиск, потому что я не добавил его в закладки. Просто лучшее объяснение ООП против ФП для тех, кто понимает преимущество понимания концепций, а не методов. Бумага о проблеме выражения тоже фантастическая. Большое спасибо за то, что поделились своим мнением, на мой взгляд, ваш ответ очень недооценен.
tobiak777
4

Там нет реального против. Они могут быть совершенно дополнительными. Есть языки FP, которые поддерживают ООП. Но сообщества отличаются тем, как они управляют модульностью.

Пользователи языков FP стремятся достичь модульности через математические законы. И предпочитаю доказательства, чтобы показать соответствие их законам.

В обязательном порядке пользователи ООП, как правило, фиксируют поведение объекта в тест-кейсах, которое можно запустить повторно, если объект изменился, и достичь таким образом модульности.

Это всего лишь маленький аспект, но я думаю, что стоит упомянуть.

Эдгар Клеркс
источник
2

Аналогия:

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

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

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

Марио Т. Ланца
источник
прекрасная аналогия, спасибо !! Не могли бы вы (если возможно) расширить эту аналогию с за и против в этих двух подходах.
Рахул Агарвал