Коли використовувати функціональну мову програмування?


90

У яких ситуаціях слід вибрати функціональну мову програмування над більш детальною об’єктно-орієнтованою мовою, такою як C ++, C # чи Java?

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


Відповідь на це питання тут stackoverflow.com/questions/381685 / ...
krosenvold

2
Завжди. Або принаймні ніколи ніколи.
Шелбі Мур III

1
З лямбдами C # є прикордонним функціоналом.
JD

Відповіді:


51

На мою думку, функціональні мови корисні в основному для двох речей: ігрових ШІ та математичних обчислень. Це добре в ігрових ШІ завдяки його приємним маніпуляціям зі списками (принаймні в Lisp та Scheme), а також для математичних обчислень через його синтаксис. Scheme, Lisp та Haskell мають синтаксис, що полегшує читання математичних обчислень. Останнє, що я повинен додати, - це те, що функціональні мови - це справді веселі мови. Мій курс «Схема» був одним із курсів, з якими я найбільше розважався.


2
Після того, як я перебрав той факт, що мій мозок хотів вибухнути на моєму першому тижні курсу компілятора, який я пройшов у схемі, я також виявив, що це було дуже весело (і мені це стало набагато краще, хе-хе)
Алекс Бараноський

1
Які функціональні мови ви використовували для математичних обчислень?
Жуль

8
Також, компілятори! Я чув, як люди, які писали компілятори в Haskell, говорили, що "ніколи більше не писатимуть компілятор імперативною мовою".
ShreevatsaR

1
julesjacobs: Я використав трохи і haskell, і Scheme для розв’язання простих математичних обчислень. Я зовсім не добре володію цими мовами, тому я маю шлях вирішити складніші проблеми. Наразі я просто не можу зробити їх досить швидкими.
Martiert

96

Я сам кілька разів досліджував це питання і думав, що міг би додати КОНКРЕТНІСТЬ до списку причин використання функціональної мови. Побачте, що в якийсь момент найближчим часом швидкість процесора не зможе збільшитися за допомогою тієї ж технології процесора. Фізика архітектури цього не дозволяє.

Отже, саме тут надходить паралельна обробка.

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

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

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


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

2
Дякуємо, що зв’язали цю статтю. Це справді допомогло мені пояснити речі.
guptron

13

Один мій друг процитував одного зі своїх викладачів коледжу приблизно наступне:

Намалюйте сітку з типами даних вгорі та операціями над цими типами даних зліва. Якщо ви розрізаєте сітку вертикально, ви робите ОО; якщо розрізати сітку горизонтально, ви робите FP.

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

  1. Чи є у вас час вкластися у вивчення нового позначення та нового способу мислення?
  2. Яка з мов, які ви розглядаєте, має достатньо багаті бібліотеки, щоб ви не застрягли, вигадуючи щось колесо?

Що стосується першого питання, якщо ви робите це в першу чергу для цілей навчання, я б запропонував звернути увагу на Haskell , через широкий спектр допоміжних матеріалів (книги, статті, активне співтовариство тощо)

Що стосується другого питання, Haskell має гарний набір бібліотек (хоча деякі з них є більш зрілими, ніж інші), але Scala (гібридна OO-функціональна мова, що працює на JVM) має ті переваги, що ви можете більш поступово переходити до функціонального стилю , і у вас є повний спектр доступних для Java бібліотек.


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

9

Практично все, що ви можете зробити в PP, можна зробити в FP, і те саме навпаки. Це просто ще один спосіб кодувати щось - інший погляд на проблему та інший спосіб її вирішення.

Однак, оскільки мало хто використовує FP, проблема полягає більше у відсутності хороших бібліотек, переносимості / ремонтопридатності (оскільки у супровідника більше шансів зрозуміти щось написане на C ++, ніж у схемі), а також у відсутності документації та спільноти. Я знаю, що Є кілька документів, проте порівняйте їх із C ++, C # або Java, і ви зрозумієте, що я маю на увазі.

Однак, якщо ви дійсно хочете зробити FP, ви можете використовувати цей стиль навіть у C ++ та C #. Звичайно, це не буде 100% FP, якщо ви використовуєте стандартну бібліотеку. На жаль, я не думаю, що C # оптимізований для використання з функціональним програмуванням, і це, мабуть, створить багато проблем із продуктивністю.

Це більше суб’єктивний пост, що я думаю про FP. Це не сувора декларація.


8
"Практично все, що ви можете зробити в PP, можна зробити в FP" - Насправді, це точно все.
BlueRaja - Danny Pflughoeft 02

2
@BlueRaja - Ви маєте на увазі повноту Тьюрінга? Якщо так, те, що ви говорите, не слідує. Наприклад, "Гра життя" Конвея закінчується Тьюрінгом, але ви не можете використовувати його для написання драйвера відеокарти, як це можливо в C. Так само я не бачу жодної з останніх ігор, написаних на Haskell. Може зробити в FP! = Теоретично міг би зробити в теоретичному FP.
Луїджі Плінге

@Luigi Plinge Я мав би погодитися з BlueRaja. Хаскеллери обговорюють деякі драйвери Linux, написані на Haskell. У мене немає посилання, але я також чув, що на Haskell була написана ОС (можливі й інші функціональні мови). Що стосується ігор, я не бачу, щоб останні ігри писалися на C # або Java, ви натякаєте, що їх не можна використовувати для таких? У будь-якому випадку, приклад гри, написаної на FP. Крім того, майте на увазі, що більшість моїх посилань - це Haskell, ЧИСТО функціональна мова.
austinprete

@PardonMyRhetoric Ви, очевидно, можете писати ігри в Haskell і робити будь-які обчислення, але швидкість буде в кілька разів меншою, а використання пам'яті вище. Отже, контраприкладом до твердження BlueRaja може бути те, що ви не можете написати "гру, яка є такою ж швидкою і використовує стільки пам'яті, що в C" у FP. Це справжнє практичне питання, а не педантичний фокус (і я зовсім не хочу бити FP - я зараз кодую Scala!).
Luigi Plinge

1
@PardonMyRhetoric Він також повинен бути ідіоматичним FP. Тести, які ви бачите, що дають продуктивність Haskell, що наближається до C, написані в "низькорівневому" унідіоматичному стилі, який більшість програмістів Haskell не могли написати. Наприклад, ви можете досягти подібної продуктивності, просто зробивши вихідний код коду Haskell і скомпілювавши код C. Хоча безглуздо. Пов’язане практичне питання стосується того, що «ти можеш зробити» проти того, що «можна / можна зробити». Якщо щось просто занадто складно, насправді не має великого значення, чи можливо це теоретично (і "можливо" для кого?).
Luigi Plinge

4

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

Як би ви відповіли на запитання "Коли використовувати об'єктно-орієнтовану мову програмування?"?


1
"Коли використовувати об'єктно-орієнтовану мову програмування?" Коли ви хочете обчислювати що-небудь, з іншого боку, я шукав проблему, яка б була інтуїтивно зрозумілою відповіддю fp, я все ще шукаю, саме так я знайшов цю публікацію.
jimjim

@Arjang Я гадаю, функціональне програмування знайшло б величезне застосування в додатках для обчислення, які потребують лише вхідних даних для отримання вихідних даних. Відсутність змін і відсутність ітерацій
EdgeDev

3

Хоча це досить суб'єктивне питання, я хотів би лише додати, що функціональні мови часто використовуються для синтаксичного аналізу доменних мов ; функціональний характер добре піддається синтаксичному аналізу граматики.


2
Розбір DSL? Я думав, що з макросами Lisp тощо, DSL реалізовані як макроси, а не те, що аналізується програмами Lisp. YMMV з іншими мовами. :-P
Кріс Джестер-Янг

1

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


2
@JonHarrop - Хочете детальніше це обговорити? Я не вважаю це настільки очевидним, і було б соромно, якби у вас склалося враження, що ви виборюєте людей з простого підсилення.
TED

1
Родина мов ML була спеціально розроблена для метапрограмування з додаванням складних мовних функцій, таких як узгодження шаблонів для маніпулювання деревами (наприклад, дерева виразів). Отже, ця родина мов за своєю суттю набагато краща у виконанні цього конкретного завдання.
JD

1
@JonHarrop - я прийму це. Однак ви говорите про ML, а не про функціональні мови загалом. Я дуже вірю в DSL, тому я впевнений, що не буду сперечатися проти використання тієї чи іншої мови саме для того завдання, для якого вона була розроблена.
TED

На сьогодні узгодження шаблонів зустрічається майже у всіх функціональних мовах, включаючи OCaml, F #, Scala, Haskell, Clojure та Erlang. Наприклад, нещодавно я створив спеціальний механізм ділових правил для клієнта з акцентом на математиці. Це 1000 рядків F # і є переважно інтерпретатором. Лексинг, синтаксичний аналіз, перевірка типу та інтерпретація введення набагато простіші завдяки збігу шаблонів.
JD

@JonHarrop .. але не всі. Це не властива функціональним мовам, саме про це було запитання.
TED

1

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

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

Зауважте також, що можна імітувати FP в межах мов OO за допомогою продуманих API. Наприклад, я бачив численні бібліотеки Java (JMock - один із прикладів), які використовують ланцюжок методів для імітації FP DSL. Тоді ви побачите такі конструкції, як:

logger.expects(once()).method("error") .with( and(stringContains(action),stringContains(cause)) );

Це по суті створює функцію, яка обчислюється, щоб визначити, чи правильна якась послідовність викликів на макетному об'єкті. (приклад викрадено з http://www.jmock.org/yoga.html )

Іншим FP-подібним синтаксисом в інших мовах OO є використання замикань, таких як Ruby.


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