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


90

В каких ситуациях я должен выбрать использование функционального языка программирования вместо более подробного объектно-ориентированного языка, такого как C ++, C # или Java?

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


На этот вопрос ответят здесь stackoverflow.com/questions/381685/…
krosenvold

2
Всегда. Или, по крайней мере, никогда.
Шелби Мур III

1
С лямбдами C # практически функциональна.
JD

Ответы:


51

На мой взгляд, функциональные языки хороши в основном для двух вещей: игрового ИИ и математических вычислений. Он хорош в игровых ИИ из-за хороших манипуляций со списками (по крайней мере, в Lisp и Scheme), и для математических вычислений из-за его синтаксиса. Scheme, Lisp и Haskell имеют синтаксис, упрощающий чтение математических вычислений. Последнее, что я должен добавить, это то, что функциональные языки - действительно забавные языки. Мой курс Scheme был одним из тех, от которых мне было больше всего весело.


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

1
Какие функциональные языки вы использовали для математических вычислений?
Жюль

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

1
julesjacobs: Я использовал как haskell, так и Scheme для решения простых математических вычислений. Я не очень хорошо владею этими языками, поэтому у меня есть способ решать более сложные проблемы. Я просто не могу пока сделать их достаточно быстрыми.
Martiert

96

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

Вот тут и появляется параллельная обработка.

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

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

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


38
Я бы не сказал, что большинство объектно-ориентированных языков не могут использовать произвольно большое количество процессоров. Я бы сказал, что для того, чтобы программа могла использовать преимущества многих процессоров одновременно эффективным и надежным образом, эта программа должна быть организована таким образом, чтобы большинство ресурсоемких единиц кода вели себя как чистые функции. Таким образом можно организовать программу на большинстве языков. На функциональных языках это сделать проще, чем на императивных (в том числе объектно-ориентированных).
Zak

2
Спасибо за ссылку на эту статью. Это действительно помогло мне кое-что объяснить.
abc123

13

Один мой друг процитировал одного из профессоров его колледжа, который сказал примерно следующее:

Нарисуйте сетку с типами данных вверху и операциями с этими типами данных внизу слева. Если вы разрезаете сетку вертикально, вы выполняете объектно-ориентированный подход; если вы разрезаете сетку по горизонтали, вы выполняете FP.

Я отвечу, что FP - это вполне жизнеспособный подход к программированию с таким же широким спектром приложений, как объектно-ориентированный подход. Как и в случае любого обсуждения выбора языка программирования, я думаю, что наиболее важными вопросами являются:

  1. У вас есть время, чтобы научиться новым обозначениям и новому образу мышления?
  2. Какие из языков, которые вы рассматриваете, имеют достаточно богатые библиотеки, чтобы вы не застряли, изобретая колесо?

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

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


Я изучил Scheme в колледже, поэтому я не хочу изучать функциональное программирование только ради опыта. Я бы предпочел выучить какой-нибудь функциональный язык из практических соображений.
Alex Baranosky

9

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

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

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

То, что я думаю о FP, это скорее субъективный пост. Это не строгое заявление.


8
«Практически все , что вы можете сделать в PP можно сделать FP» - На самом деле, это точно все.
BlueRaja - Дэнни Пфлугхёфт,

2
@BlueRaja - вы имеете в виду полноту по Тьюрингу? Если да, то то, что вы говорите, не следует. Например, «Игра жизни» Конвея - это Turing Complete, но вы не можете использовать ее для написания драйвера видеокарты, как это можно сделать в C. Точно так же я не вижу ни одной из последних игр, написанных на Haskell. Можно сделать в FP! = Теоретически может сделать в теоретическом FP.
Луиджи Плиндж

@Luigi Plinge Я бы согласился с BlueRaja. Haskellers обсуждает некоторые драйверы Linux, написанные на Haskell. У меня нет ссылки, но я также слышал, что операционная система была написана на Haskell (возможно, и на других функциональных языках). Что касается игр, я не вижу последних игр, написанных на C # или Java, вы подразумеваете, что они не могут быть использованы для таких? Во всяком случае, пример игры, написанной на FP. Также имейте в виду, что большинство моих ссылок - это Haskell, ИСТИННО функциональный язык.
austinprete

@PardonMyRhetoric Очевидно, вы можете писать игры на Haskell и выполнять любые вычисления, но скорость будет в несколько раз медленнее, а использование памяти выше. Таким образом, контрпример к утверждению BlueRaja может заключаться в том, что вы не можете написать «игру, которая работает так же быстро и использует столько памяти, сколько в C» в FP. Это реальный практический вопрос, а не педантичный трюк (и я вовсе не собираюсь критиковать FP - я кодирую Scala прямо сейчас!).
Луиджи Плиндж

1
@PardonMyRhetoric Это тоже должен быть идиоматический FP. Тесты, которые вы видите, которые дают производительность Haskell, приближающуюся к производительности C, написаны в унидиоматическом стиле «низкого уровня», который большинство программистов Haskell написать не смогли. Например, вы можете добиться аналогичной производительности, просто создав свой код Haskell и скомпилировав код C. Хотя бессмысленно. Смежный практический вопрос состоит в том, что «вы можете сделать» и что «можно / можно было бы сделать». Если что-то слишком сложно, на самом деле не имеет большого значения, возможно ли это в теории (и «возможно» для кого?).
Луиджи Плиндж

4

Функциональные языки хороши во многих ситуациях. Это зависит от библиотек конкретного функционального языка.

Как бы вы ответили на вопрос «Когда использовать объектно-ориентированный язык программирования?»?


1
«Когда использовать объектно-ориентированный язык программирования?» С другой стороны, когда вы хотите что-либо смоделировать с помощью вычислений, я искал проблему, интуитивно понятным ответом на которую будет fp, я все еще ищу, вот как я нашел этот пост.
jimjim 01

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

3

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


2
Разбор DSL? Я думал, что с макросами Лиспа и т.п. DSL реализованы как макросы, а не как то, что нужно анализировать программами на Лиспе. YMMV с языками, отличными от Lisp. :-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 на языках объектно-ориентированного программирования с помощью грамотно разработанных API. Например, я видел множество библиотек Java (JMock - один из примеров), которые используют цепочку методов для имитации FP DSL. Затем вы увидите такие конструкции, как:

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

По сути, это создает функцию, которая оценивается, чтобы определить, правильна ли некоторая последовательность вызовов для фиктивного объекта. (пример украден с http://www.jmock.org/yoga.html )

Другой похожий на FP синтаксис в других объектно-ориентированных языках - это использование замыканий, например, в Ruby.


2
«... неважно, какой из них вы выберете с точки зрения того, какие проблемы вы можете решить». Только если у вас есть бесконечное количество времени и денег на решение вашей проблемы.
JD

0

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

  • обработка без сохранения состояния
  • математические уравнения, включая ML (машинное обучение)
  • неизменные процессы
  • когда вам нужен масштабируемый параллелизм
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.