Функціональне програмування проти OOP [закрито]


93

Я пізніше чув багато розмов про використання функціональних мов, таких як Haskell. Які є великі відмінності, плюси та мінуси функціонального програмування проти об'єктно-орієнтованого програмування?


27
Одне не відкидає іншого.
mbq

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)

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


12
Слід зазначити, що функціональна версія є рекурсивною та таким чином оптимізована, щоб уникнути переповнення стека. (Деякі люди можуть побачити рекурсію і вважають, що функціональне програмування є поганим через це)
альтернатива

3
+1 для опису найважливішого аспекту імперативу та функціоналу: управління потоком проти потоку даних. Я мушу додати, що функціональна парадигма та парадигма ОО не є взаємовиключними; ви можете використовувати парадигму ОО для моделювання взаємодії об'єкта (даних), а функціональну парадигму для перетворення (маніпулювання) цим об'єктом.
Лі Лі Райан

1
Цікаво, що ви можете моделювати дані як контроль і контроль як дані, а також перемішувати. FP може використовувати стрілки та функції першого порядку для передачі потоку управління навколо та маніпулювання ним, як дані. OOP використовує різні шаблони проектування для використання об'єктів для зміни керуючого потоку.
CodexArcanum

Я думаю, що також варто відзначити, що головна відмінність полягає не в тому, що ви пишете ту саму програму, але ви робите свої петлі хвостово-рекурсивними методами викликів. це значно більше, ніж це
Сара

Ваш функціональний приклад використовує відповідність шаблонів параметрів. Це не виключно для функціонального програмування, аналогічно функціональні програми можуть використовувати монади і навіть імперативні конструкції, не обов'язково формулювати кожен ітераційний алгоритм як рекурсивний алгоритм.
Дай

16

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

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

Якщо ні для чого іншого, то вивчення функціонального програмування корисно для понять, які він містить. Це змінить те, як ви займаєтесь програмуванням і думати про програмування. І я б здогадався, що в майбутньому функціональне програмування буде настільки ж важливим, як і об'єктно-орієнтоване програмування.

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

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


Які є великі відмінності, плюси та мінуси функціонального програмування проти об'єктно-орієнтованого програмування?

Добре об'єктно-орієнтоване програмування приємно, оскільки дозволяє моделювати складну проблему в ієрархії, щоб ви могли спростити проблему. Але стає дуже важко, коли ви починаєте розглядати багатопотокове програмування під час використання об'єктів, що змінюються. У таких випадках потрібно широко використовувати об’єкти синхронізації, і вдосконалити велике додаток майже неможливо.

Ось де відбувається функціональне програмування. Через такі речі, як незмінність, функціональне програмування дійсно спрощує багатопотокові програми. Це майже тривіально легко паралелізувати щось, коли ви знаєте, що при введенні X у функцію він завжди виводить Y. Також ви знаєте, що змінна (або значення у функціональному програмуванні) не може змінити середнє використання з іншого потоку.


2
Щоб було зрозуміло, схема аж ніяк не є чисто функціональною мовою.
Джонатан Стерлінг

5
Ваш другий останній абзац - це повністю. OO не створює жодних проблем у багатопотоковій роботі. Здається, ви плутаєте імперативне програмування з об'єктно-орієнтованим програмуванням. Це так?
зниклий фактор

5
@missingfaktor: Ні, я не плутаю поняття. Об'єкт, як правило, має аксесуари, модифікатори, члени даних та функції членів. Так, не всі об'єкти повинні мати модифікатори, і ви можете реалізувати їх як незмінні. Але якщо ви подивитеся на будь-яку довільну програму OO, вона майже напевно матиме декілька об'єктів, які мають модифікатори, але вони все ще використовуються декількома потоками. Тобто в парадигмі ООП досить рідко є все незмінне.
Брайан Р. Бонді

Ви повинні прочитати відповіді на це питання: stackoverflow.com/questions/3949618/fp-and-oo-orthogonal/…
пропущений фактор

Також перевірте відповідь Френка Ширара тут: programmers.stackexchange.com/questions/12423/…
пропущено

8

(Ця відповідь адаптована з відповіді на закрите запитання в StackOverflow .)

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

  • Об'єктно-орієнтовані мови хороші, коли у вас є фіксований набір операцій над речами , і коли ваш код розвивається, ви в першу чергу додаєте нові речі. Це можна досягти, додавши нові класи, які реалізують існуючі методи, а існуючі класи залишаються в спокої.

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

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

  • Додавання нової операції до об'єктно-орієнтованої програми може потребувати редагування багатьох визначень класів, щоб додати новий метод.

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

Ця проблема добре відома вже багато років; у 1998 році Філ Вадлер назвав це "проблемою вираження" . Хоча деякі дослідники вважають, що проблему вираження можна вирішити за допомогою таких мовних особливостей, як міксин, загальновизнане рішення поки що не потрапило в мейнстрім.


Я люблю вашу відповідь, слово мудрості тут. Я познайомився з ним кілька місяців тому і просто провів 30 хвилин, спеціально шукаючи це, оскільки не робив закладки. Просто найкраще пояснення на OOP проти FP для тих, хто розуміє перевагу розуміння понять, а не технік. Документ про проблему вираження також фантастичний. Велике спасибі за те, що поділилися вашою думкою, на мою думку, ваша відповідь дуже занижена.
tobiak777

4

Реального проти. Вони можуть ідеально доповнювати один одного. Існують мови FP, які підтримують OOP. Але громади відрізняються тим, як вони обробляють модульність.

Користувачі мов FP прагнуть досягти модульності за допомогою математичних законів. І віддайте перевагу доказам, щоб показати дотримання своїх законів.

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

Це лише невеликий аспект, але я думаю, що це варто згадати.


2

Аналогія:

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

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

Перший (ООП) сприймає ідею змінити речі на місці, а другий (ФП) уникає цього. Обидві є парадигмами державного управління. Обидва можуть, використовуючи різні стратегії, зафіксувати ефект заповнення заявки на роботу. OOP безпосередньо змінює стартовий інструмент, тоді як FP накладає те, що було раніше, щоб вплинути на появу змін .


прекрасна аналогія, THX !! Ви не заперечуєте (якщо можливо) розширити цю аналогію із плюсами та мінусами у цих двох підходах.
Рахул Агарвал
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.