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


50

В последнее время я слышал много энтузиазма по поводу функциональных языков программирования в отношении Scala, Clojure и F #. Я недавно начал изучать Haskell, чтобы изучить парадигму FP.

Я люблю это, это действительно весело, и соответствует моему математическому фону.

Но будет ли это когда-нибудь действительно важно? Очевидно, это вряд ли новая идея.

Вот мои вопросы:

  1. Что способствовало недавнему энтузиазму FP? Это просто скука с ОО или что-то изменилось, чтобы сделать ФП более необходимым, чем раньше?
  2. Это свидетельствует о будущем FP? Или это модно, как объектно-ориентированные базы данных?

Другими словами, может ли кто-нибудь помочь мне понять, откуда это и куда оно может идти?



13
Не дубликат - это вопрос о том, почему люди внезапно начинают суетиться, поскольку это не новая идея (хотя этот вопрос требует больше объективных различий).
Питер Боутон

2
Люди суетятся из-за FP в последнее время? Для меня новость, я думал, что это всегда был случай, когда какая-то группа суетилась о том, как FP собирается завладеть миром императивного программирования.
Chris

1
Я думаю, что я уже ответил на этот вопрос в StackOverflow.
Кен Блум

1
Да, FP уже был стар, я думаю, когда я использовал Scheme в качестве старшекурсника в Колумбии в 1989 году. Я думаю, это блестящая новая вещь.
Тим

Ответы:


33

Одним из основных нововведений в FP, приведших к «взрыву» интереса, являются монады.

В январе 1992 года Филипп Вадлер написал статью «Сущность функционального программирования», в которой монады вводятся в функциональное программирование как способ борьбы с IO.

Основной проблемой с чистыми, ленивыми, функциональными языками программирования была полезность при работе с IO. Это один из членов «Неуклюжего отряда» в программировании, потому что «лень и побочные эффекты, с практической точки зрения, несовместимы. Если вы хотите использовать ленивый язык, это в значительной степени должен быть чисто функциональный язык; если вы хотите использовать побочные эффекты, вам лучше использовать строгий язык ". Ссылка

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

Как монады решают проблему IO? Что ж, не обсуждая слишком много монад, они в основном принимают «Мир» (среду выполнения) в качестве входных данных для монады и создают новый «Мир» в качестве выходных данных, и в результате: type IO a = World -> (a, Мир).

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

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


Очень информативно, спасибо. Я принимаю этот ответ не потому, что он прав, а другие неправы (я проголосовал несколько), а потому, что я думаю, что он заслуживает наглядности.
Эрик Уилсон

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

@Richard: «type IO a = World -> (a, World)» звучит слишком хорошо, чтобы быть правдой (я думал, что никогда не получу монад). Я предполагаю, что вы сравниваете LINQ с монадами, потому что, когда вы передаете лямбду в оператор LINQ, лямбда «видит» всю свою среду, верно?
Стефан Монов

@ Стефан: Звучит довольно точно, что лямбда видит окружающую обстановку, но я не уверен на 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

потому что вы должны подготовить ингредиенты, прежде чем использовать их.

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

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

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


3
Это было верно в 1950 году, конечно.
Эрик Уилсон,

1
@FarmBoy, не совсем, но это сегодня.

5
Чем это отличается от внедрения зависимости?
Билл К

2
@ Билл К, отличное наблюдение - я сам этого не установил. Разница в том, что объекты для инъекции - по крайней мере, в Java - оцениваются с нетерпением, а не лениво. Вы не можете ввести бесконечный список.

1
@ Thorbjørn Ravn Andersen Я не совсем уверен, что понимаю, почему был бы полезен бесконечный список. Можете ли вы на самом деле выполнить сумму операций типа (бесконечный список)? Кажется очень маловероятным. В противном случае это просто звучит так, как Java использует итераторы, вы просто кодируете итератор таким образом, что он создает экземпляры объектов только тогда, когда вы их запрашиваете - не совсем бесконечно, но бесконечно (есть БОЛЬШАЯ разница, а? )
Билл К

21

В конце 80-х - начале 90-х компьютеры стали достаточно мощными для ООП в стиле Smalltalk. В настоящее время компьютеры достаточно мощные для FP. FP программирует на более высоком уровне и, следовательно, часто - в то время как более приятное программирование - не самый эффективный способ решить определенную проблему. Но компьютеры настолько быстрые, что тебе все равно.

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

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


6
Собирался добавить ответ, но вы затронули мою точку зрения в своем последнем предложении; Функциональное программирование будет становиться все более и более распространенным, так как число ядер в одной машине увеличивается. Врожденное отсутствие состояния облегчает механическое разделение функциональных программ по процессорам (это означает, что если у вас есть чисто функциональная программа, компилятор может теоретически позаботиться о параллелизме для вас с минимальными усилиями с вашей стороны, смотрите youtube.com/watch? v = NWSZ4c9yqW8 для обсуждения параллелизма данных).
Инамати

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

Обратите внимание, что мой первый комментарий был написан до того, как ответ был отредактирован и содержал дополнительное утверждение.
Инамати

Простите за это. Я просто забыл этот момент.
LennyProgrammers

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

7

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

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

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

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

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

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

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

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


2
Вопрос состоит в том, чтобы спросить о преимуществах FP-подобных языков . То, что вы описали, можно сделать и с использованием традиционных языков.
Pacerier

6

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

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


5

Я думаю, что основным ответом на этот вопрос является «разоблачение».

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

В последнее время появилось несколько языков, набирающих популярность в основном потоке, которые используют мультипарадигмальный подход; F # , JavaScript является ярким примером.

В частности, JavaScript, особенно при использовании с языком фреймворков с функциональным стилем, таким как jQuery или Prototype , становится повседневным языком для многих из-за всей работы на современных динамичных веб-сайтах. Такое знакомство с функциональным стилем заставляет людей осознать силу, которую он предоставляет, особенно когда человек может вернуться к императивному стилю по желанию.

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

Поскольку F # становится первоклассным языком в Visual Studio 2010, а jQuery (и др.) Становится настолько важным, становится реалистичным использование этих языков, а не просто что-то непонятное для игры или создания изолированных программ.

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


3

В этом выступлении Андерс Хейлсберг объясняет свой взгляд на эту тему.

[РЕДАКТИРОВАТЬ]

Извините, ссылка была неправильной. Теперь это указывает на правильное место.

Чрезвычайно краткое резюме некоторых моментов часового разговора:

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

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


1
Не могли бы вы подвести итог?

1
@Thorbjorn Это напоминает мне человека, который не мог подвести итог . (Не направляя это на вас, ответьте автору.)
Марк С

1
Ссылка даже не указывает на правильное место.
Кен Блум

2

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

В Ruby on Rails весь подход к функциональному программированию резко упал, поскольку он предложил очень быстрый путь к функциональному (хе-хе) веб-приложению. На SO есть интересная дискуссия об этом, и один конкретный ответ выделяется:

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

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

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


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

@Mladen Хммм, возможно ли, что вы связываете состояние связи клиент-сервер (HTTP) с состоянием приложения (DAO и т. Д.)? Цитата Стефана Тилкова отсюда ( codemonkeyism.com/stateless-applications-illusion ) "В веб-приложении каждый отдельный запрос должен содержать достаточно информации для обработки независимо от того, был ли предыдущий запрос или нет. Постоянный ресурс на стороне сервера состояние в порядке, состояние на стороне клиента в порядке, переходное состояние связи (сеанса) - не потому, что оно разрушит масштабируемость и возможность закладки ». Это основа ОТДЫХА.
Гари Роу

1
Вы можете прочитать paulgraham.com/avg.html, чтобы лучше понять, почему так мало объявлений о поиске работы ищут разработчики Lisp.

@ Thorbjørn Ravn Andersen Хорошая статья. Вдохновляет меня вырвать мой редактор Lisp.
Гари Роу

1

Функциональное программирование дает мне такое же ощущение покалывания « вау, это ново », как когда я впервые начал баловаться с объектами много лет назад.

Я понимаю, что FP - далеко не новая концепция, но и OO не было, когда она получила реальный прорыв в девяностых, когда «все» неожиданно вышли из процедурного программирования. Во многом это было связано со своевременным успехом Java, а затем и C #.

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


ОО намного моложе, чем ФП, но он попал в центр внимания гораздо раньше. Я думаю, скобки напугали слишком много людей
Хавьер

1

Вот мои вопросы: 1. Что способствовало недавнему энтузиазму FP? Это просто скука с ОО или что-то изменилось, чтобы сделать ФП более необходимым, чем раньше? 2. Является ли это показателем будущего ФП? Или это модно, как объектно-ориентированные базы данных?

Другие дали хорошую техническую причину.

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

Его будущее широкое использование будет, если обещание реально и выполнено.


Это большое «если». COBOL, «на английском» означало, что любой может программировать. ИИ собирался сделать программирование устаревшим. ОО собирался сделать программирование таким же простым, как сборка тинкертой. Кодеры, как рок-фанатки, всегда ищут «следующую большую вещь», и одну после
нее

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.