Чому нинішній ентузіазм щодо функціонального програмування? [зачинено]


50

Останнім часом я чую багато ентузіазму щодо функціональних мов програмування стосовно Scala, Clojure та F #. Нещодавно я почав вивчати Haskell, щоб вивчити парадигму FP.

Мені подобається, це дійсно весело і відповідає моєму математичному фону.

Але чи це колись насправді має значення? Очевидно, навряд чи це нова ідея.

Ось мої запитання:

  1. Що сприяло останнім захопленням ПП? Це просто нудьга з ОО, чи щось змінилося, щоб зробити ПП більш потрібним, ніж раніше?
  2. Чи це свідчить про майбутнє ПП? Або це примха, як об’єктні бази даних?

Іншими словами, чи може хтось допомогти мені зрозуміти, звідки це походить і куди воно може йти?



13
Не дублікат - це питання, чому люди раптом метушаться, оскільки це не нова ідея (в той час як це питання задає більше об'єктивних розбіжностей).
Пітер Бауфтон

2
Люди останнім часом метушаться через ПП? Для мене новина, я думав, що це завжди було так, що якась група шумить, як FP збирається перейняти імперативний світ програмування.
Кріс

1
Я думаю, що раніше я відповідав на це питання на StackOverflow.
Кен Блум

1
Так - FP був уже старий. Я думаю, коли я використовував схему як недоїзд у Колумбії в 1989 році. Я думаю, що це блискуча нова річ.
Тім

Відповіді:


33

Одне з головних нововведень FP, яке призвело до "вибуху" інтересу, - монади.

У січні 1992 р. Філіп Вадлер написав документ під назвою «Сутність функціонального програмування», в якому монади ввели функціональне програмування як спосіб боротьби з ІО.

Головною проблемою з чистими, ледачими, функціональними мовами програмування була корисність у роботі з IO. Це один з членів "Невдалого загону" в програмуванні, оскільки "лінь і побічні ефекти з практичної точки зору несумісні. Якщо ви хочете використовувати ледачу мову, це, мабуть, має бути суто функціональною мовою; якщо ви хочете використовувати побічні ефекти, вам краще використовувати сувору мову ". Довідково

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

Як монади вирішують проблему ІО? Ну, не надто обговорюючи монади, вони в основному приймають "Світ" (середовище виконання) як вхід до монади, і створюють новий "Світ" як вихід, і результат: введіть IO a = World -> (a, Світ).

Таким чином, ПП все більше і більше входить в мейнстрім, оскільки найбільша проблема - IO (та інші) вирішена. Інтеграція в існуючі мови ОО також відбувається, як відомо. LINQ - це монади, наприклад, наскрізь.

Для отримання додаткової інформації я рекомендую почитати про монади та статті, на які посилається у моїй відповіді.


Надзвичайно інформативні, дякую. Я приймаю цю відповідь не тому, що вона правильна, а інші - неправі (я вже схвалила декілька), а тому, що я вважаю, що вона заслуговує на це наочність.
Ерік Вілсон

Більш релевантним прикладом може бути type IO a = UI -> (a, UI)фантастична відповідь.
ChaosPandion

@Richard: "тип IO a = World -> (a, World)" звучить майже занадто добре, щоб бути правдою (я думав, що ніколи не отримаю монади). Я думаю, ви уподібнюєте LINQ монадам, тому що коли ви передаєте лямбду оператору LINQ, лямбда "бачить" все її середовище, чи не так?
Стефан Монов

@Stefan: Звучить дещо точно, щоб сказати, що лямбда бачить, що це оточення, але я не на 100% зрозуміла з цього приводу, тому я вагаюся відповідати, поки сама не дізнаюся більше. Однак я можу сказати зі 100% впевненістю, що LINQ - це монади, тому що творці говорили так багато разів. SelectMany точно еквівалентний Bind в Haskell. Якщо ви ще не читали " Дива монад" ( blogs.msdn.com/b/wesdyer/archive/2008/01/11/… ), я настійно рекомендую це ... воно розкриє, наскільки LINQ насправді монади. Ура.
Річард Ентоні Хайн

1
@Job, див. Blogs.msdn.com/b/wesdyer/archive/2008/01/11/… як зазначено у коментарі вище.
Річард Ентоні Хайн

30

Однією з головних проблем при програмуванні традиційних мов, таких як C, Java, C #, ассемблер тощо, є те, що у вас незграбна послідовність кроків, які ви повинні виконати, щоб виконати задане завдання, оскільки для початку вам потрібно підготувати всі залежності і Їхні залежності раніше

Приклад: для того, щоб зробити A, у вас повинні бути присутні B і C, а B залежить від D і E, в результаті чого виходить щось на зразок

  • D
  • Е
  • С
  • Б
  • А

тому що ви повинні мати готові інгредієнти, перш ніж їх використовувати.

Функціональні мови, особливо ледачі, перевертають цю з ніг на голову. Якщо дозволити A сказати, що йому потрібні B і C, і дозволити мові виконання часу визначати, коли отримати B і C (що, у свою чергу, вимагає D і E), які всі оцінюються, коли потрібно оцінити A, ви можете створити дуже малі і стислі будівельні блоки, в результаті яких утворюються невеликі і стислі програми. Ледачі мови також дозволяють використовувати нескінченні списки, оскільки обчислюються лише фактично використовувані елементи, і не потрібно зберігати всю структуру даних в пам'яті, перш ніж мати можливість її використовувати.

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

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


3
Це було вірно в 1950 році, звичайно.
Ерік Вілсон

1
@FarmBoy, не дуже, але це сьогодні.

5
Чим це відрізняється від введення залежності?
Білл К

2
@Bill K, відмінне спостереження - я такого зв’язку не робив сам. Різниця полягає в тому, що об'єкти, які потрібно вводити - принаймні на Java - нетерпляче оцінюють, а не ліниво оцінюють. Ви не можете ввести нескінченний список.

1
@ Thorbjørn Ravn Andersen Я не зовсім впевнений, я розумію, чому нескінченний список був би корисним, чи можна насправді зробити суму операцій типу (нескінченний список)? Здається, це дуже малоймовірно. Інакше це просто схоже на те, як Java використовує ітератори, ви просто кодуєте ітератор таким чином, що він створює екземпляри лише об'єктів, коли ви просите їх - не зовсім нескінченно, але нескінченно (є велика різниця, так? )
Білл К

21

В кінці 80-х - початку 90-х комп'ютери стали достатньо потужними для OOP у стилі Smalltalk. У наш час комп'ютери досить потужні для FP. FP програмує на вищому рівні і, таким чином, часто - хоча приємніше програмувати - не найефективнішим способом вирішити певну проблему. Але комп'ютери настільки швидкі, що вам все одно.

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

Також сьогодні межі мови програмування розмиті. Не потрібно відмовлятися від однієї парадигми, якщо ви хочете використовувати іншу. Ви можете робити FP на найбільш популярних мовах, щоб бар'єр для входу був низьким.


6
Збирався додати відповідь, але ви потрапили в мою точку в останньому реченні; Функціональне програмування стає все більш поширеним, оскільки кількість ядер в одній машині збільшується. Притаманна відсутність стану полегшує механічний розподіл функціональних програм на процесори (це означає, що якщо у вас суто функціональна програма, компілятор теоретично може подбати про паралелізм для вас з мінімальними зусиллями з вашого боку, див. Youtube.com/watch? v = NWSZ4c9yqW8 для обговорення паралелізму даних).
Інаіматі

1
@Inaimathi Ditto. Функціональне програмування дуже масштабоване, тому має сенс у багатоядерних архітектурах.
EricBoersma

Зауважте, що мій перший коментар був написаний до редагування відповіді, щоб містити додаткову заяву.
Inaimathi

Вибачте за це. Я просто забув цей момент.
LennyProgrammers

Чи дійсно загальновизнано, що функціональні компілятори не можуть виробляти машинний код так само оптимізовано, як OOPS? Я не можу придумати жодної теоретичної причини, чому це повинно бути правдою; і я можу придумати шляхи, що можливі більш вдосконалені оптимізації, ніж у OOPS.
Джеремі

7

Сьогоднішня потреба в розподілених обчисленнях.

FP використовує функції як будівельні блоки, які не мають стану, тому викликає їх n разів із одними і тими ж параметрами повинен завжди повертати одне і те ж значення, вони не мають побічних ефектів.

Таким чином, ви можете надіслати ту саму функцію на купу машин, щоб виконувати та виконувати роботу паралельно.

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

Поява FP (і в деякій мірі NoSQL) відбувається після розповідей про дивовижні результати обчислень у сотнях тисяч комп'ютерів, які працюють паралельно, і про те, як це легко.

Але, ймовірно, це лише ніша того типу додатків, які потребують такого типу налаштування. Для багатьох, багатьох інших програм / систем, процедурні та OO працюють просто чудово.

Отже, це все, щоб розширити наш кругозір програмування та повторно прийняти ці поняття, які, як ми думали, не виходили за межі академічних наук.

Я навчився програмувати в Ліспі років тому, і тоді я не знав, що це навіть FP. На сьогодні я забув майже все про це, але, безумовно, допомогти мені зрозуміти такі поняття, як рекурсія, дуже легко.


2
Постає питання про переваги FP-подібних мов . Те, що ви описали, можна зробити і за допомогою традиційних мов.
Pacerier

6

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

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


5

Я думаю, що головна відповідь на це питання - "вплив".

Функціональне програмування не є новим. Мене викладали Хаскеллу в університеті близько 12 років тому і любив це. Але рідко доводиться використовувати мову в моїй професійній роботі.

Останнім часом ряд основних мов набирає тяги в головному потоці, які використовують підхід з декількома парадигмами; F # , основні приклади JavaScript.

Зокрема, JavaScript, особливо якщо він використовується з мовою рамкового функціонального стилю, як jQuery або Prototype , стає щоденною мовою для багатьох людей завдяки всій роботі на динамічних сучасних веб-сайтах. Цей вплив на функціональний стиль змушує людей усвідомлювати силу, яку він надає, особливо коли людина здатна за бажанням повернутися до імперативного стилю.

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

Коли F # стає першокласною мовою в Visual Studio 2010, а jQuery (та ін.) Стає настільки важливим, що використовувати ці мови стає реалістичним, а не просто чимось незрозумілим для того, щоб грати чи робити окремі програми.

Пам’ятайте, що код повинен бути доцільним - критична маса розробників повинна використовувати та підтримувати мови, щоб компанії відчували себе безпечно у використанні.


3

У цій бесіді Андерс Хейльсберг пояснює свою точку зору на цю тему.

[EDIT]

Вибачте, посилання було невірним. Тепер він вказує на потрібне місце.

Надзвичайно короткий підсумок деяких моментів одногодинної бесіди:

Функціональні мови дозволяють декларативніше стилю програмування, ніж процедурні мови, тому програми, написані на FLs, зазвичай зосереджуються більше на тому, що замість того, як . Через свою елегантну математичну структуру FL також зручніше оптимізувати та трансформувати компіляторами, що також дозволяє легко мета-програмування та побудова вбудованих DSL. Все це разом робить функціональні програми більш лаконічними та самодокументованими, ніж процедурні програми.

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


1
Не могли б ви підсумувати?

1
@Thorbjorn Це нагадує мені людину, яка не змогла підвести підсумки . (Не звертаючи на це уваги, відповідайте автором.)
Марк C

1
Посилання навіть не посилається на потрібне місце.
Кен Блум

2

Я думаю, це пов'язане з тісним співвідношенням між функціональною парадигмою програмування та програмуванням для Інтернету.

Ruby on Rails різко полегшив весь підхід до функціонального програмування, оскільки він запропонував дуже швидкий шлях до функціонального (хе-хе-х) веб-додатку. Про цю тему ведеться цікава дискусія , і одна конкретна відповідь виділяється:

Функціональне програмування дуже добре відповідає веб-програмам. Веб-додаток отримує HTTP-запит і створює HTML-результат. Це можна вважати функцією від запитів до сторінок.

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

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


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

@Mladen Hmmm, чи можливо ви поєднуєте стан зв'язку клієнт-сервер (HTTP) із станом програми (DAO та ін.)? Цитуючи звідси Стефана Тілкова ( codemonkeyism.com/stateless-applications-illusion ) "У веб-додатку кожен окремий запит повинен містити достатню кількість інформації, яку можна обробляти незалежно від того, чи не відбувся попередній запит чи ні. Постійний ресурс на сервері стан є нормальним, стан на стороні клієнта є нормальним, перехідний стан зв'язку (сеансу) - це не тому, що це зіпсує масштабованість та закладки " Це основа REST.
Гері Роу

1
ви можете прочитати paulgraham.com/avg.html, щоб краще зрозуміти, чому не так багато оголошень про роботу шукають розробники Lisp.

@ Thorbjørn Ravn Andersen Гарна стаття. Надихає мене вийти з редактора Lisp.
Гері Роу

1

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

Я усвідомлюю, що FP - це далеко не нова концепція, але вона також не була OO, коли вона отримала свою справжню перерву в дев'яностих, коли "всі" раптом перескочили судно з процесуального програмування. Багато в чому це було зумовлено своєчасним успіхом Java та пізніше C #.

Я думаю, що те саме відбудеться і з FP з часом, коли наступна група мов почне поширюватися таким же чином. Настільки ж, як вони вже є, принаймні в деяких колах, з такими мовами, як Scala та F #.


OO набагато молодший за FP, але він потрапив у центр уваги набагато раніше. Я здогадуюсь, що дужки налякали занадто багато людей
Хав'єр

1

Ось мої запитання: 1. Що сприяло останнім захопленням ПП? Це просто нудьга з ОО, чи щось змінилося, щоб зробити ПП більш потрібним, ніж раніше? 2. Чи це свідчить про майбутнє ПП? Або це примха, як об’єктні бази даних?

Інші дали вагомі технічні причини.

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

Її в майбутньому широке використання буде, якщо обіцянка реальна і виконана.


Це велике "якщо". COBOL - "англійською" означало, що хтось може програмувати. AI збирався зробити програмування застарілим. OO збирався зробити програмування таким же простим, як і складання тинкертоев. Кодери - як скельні групи, завжди шукають "наступну велику річ", і ту, що після цього, і ту ...
Майк Данлаве

0

Я думаю, що це поєднання двох тенденцій:

  1. Функціональні функції додаються до основних мов (наприклад, C #).
  2. Створюються нові функціональні мови.

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


0

Раніше люди писали програми для запуску на робочому столі за допомогою вбудованих API операційної системи, а такі API (в основному) написані на C, тож здебільшого, якщо ви хочете написати програму для рідних API, ви написав цю програму в C.

Я думаю, що нове нововведення за останні 10 років або близько того полягає в різноманітності API, зокрема, для таких речей, як веб-розробка, де API платформ не має значення (оскільки створення веб-сторінки в основному передбачає маніпуляції з рядками). Оскільки ви не кодуєте безпосередньо Win32 API або POSIX API, це дає людині свободу випробовувати функціональні мови.


0

Це акуратно і витончено і лоскотить ваш мозок. Це добре.

Це також, ІМХО, класична стрічка. Рішення, яке шукає проблему.

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

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


-1

Безумовно, через F #, хоча іноді важко сказати, яка з них є причиною, а яка - наслідком.

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