В последнее время я заметил, что функциональные языки программирования набирают популярность . Я недавно видел, как индекс Tiobe показывает рост их популярности по сравнению с прошлым годом, хотя большинство из них даже не достигают 50 самых популярных языков по этому индексу.
И это имело место в течение достаточно долгого времени. Функциональное программирование просто не стало таким популярным, как другие модели (т.е. объектно-ориентированное программирование).
Однако я видел возрождающийся интерес к возможностям функционального программирования, и теперь, когда многоядерные технологии становятся все более и более популярными, разработчики начали проявлять интерес к другим моделям параллелизма, уже изученным в прошлом такими языками, как Haskell и Erlang.
Я с большим интересом вижу тот факт, что, несмотря на отсутствие значительного признания в сообществе, все больше и больше языков такого рода продолжают появляться. Clojure (2007), Scala (2003), F # (2002) - это всего лишь три примера последнего десятилетия.
Я сам потратил некоторое время на изучение Haskell и Scala. И я нахожу большой потенциал в парадигме, которая была для меня новой, несмотря на то, что я был там так долго.
И, конечно же, мой самый большой вопрос - станет ли какой-либо из них достаточно популярным, чтобы рассмотреть возможность приложить к ним какие-то усилия, но на этот вопрос даже Мандрейк не смог ответить, несмотря на всю суету, которую люди с ним делают.
Я хочу спросить:
- В каких сценариях мне следует рассмотреть функциональный язык программирования, более подходящий для выполнения определенной задачи? Помимо недавно популярной многоядерной проблемы параллельного программирования.
- Если бы я решил перейти на функциональный язык программирования, который вы бы назвали самыми большими подводными камнями, с которыми мне пришлось бы столкнуться? (Помимо изменения парадигмы и сложности оценки производительности из-за ленивой оценки).
- Имея так много функциональных языков программирования, как бы вы выбрали тот, который лучше соответствует вашим потребностям?
Любые рекомендации для дальнейших исследований будут приветствоваться.
Я искал в Интернете мнения, и, похоже, вся эта новая популярность исходит из идеи, что теперь мы собираемся ударить о стену закона Мура, и функциональные языки программирования придут и героически спасут нас. Но если это так, я бы сказал, что существует больше вероятностей того, что существующие популярные языки адаптируются к этой парадигме.
Некоторые из вас, с большим опытом работы с этими языками каждый день, могут предложить более глубокое понимание этого вопроса. Все ваши мнения будут лучше оценены и тщательно рассмотрены.
Заранее спасибо!
Ответы:
Все, что включает в себя создание последовательности производных элементов данных с использованием ряда шагов преобразования.
По сути, «проблема с электронными таблицами». У вас есть некоторые исходные данные и ряд построчных вычислений, которые можно применить к этим данным.
Наши производственные приложения делают ряд статистических сводок данных; к этому лучше всего подходить функционально.
Одна общая вещь, которую мы делаем, - это объединение трех чудовищных наборов данных. Подобно соединению SQL, но не так обобщенно. Далее следует ряд расчетов по полученным данным. Это все просто функциональные преобразования.
Приложение написано на Python, но написано в функциональном стиле с использованием функций генератора и неизменных именованных кортежей. Это композиция функций нижнего уровня.
Вот конкретный пример функциональной композиции.
Это один из способов, которым функциональное программирование влияет на такие языки, как Python.
Иногда такие вещи записываются так:
Неизменяемые объекты - самое сложное препятствие.
Часто вам приходится вычислять значения, которые создают новые объекты, вместо обновления существующих. Идея, что это изменчивый атрибут объекта, - это сложная умственная привычка, которую можно сломать.
Производное свойство или функция-метод является лучшим подходом. Объекты с состоянием - это сложная привычка.
Поначалу это не имеет значения. Выберите любой язык для изучения. Как только вы что-то знаете, вы можете выбрать другое, чтобы лучше соответствовать вашим потребностям.
Я прочитал о Хаскеле, чтобы понять, чего не хватает Python.
источник
«Функциональность» - это набор различных функций, каждая из которых полезна независимо друг от друга, и я считаю более полезным рассматривать каждую из них в отдельности.
неизменность
Теперь, когда я знаком с этим, каждый раз, когда мне удается вернуть неизменный результат, я всегда пытаюсь это сделать, даже в объектно-ориентированной программе. Про программу легче рассуждать, если у вас есть данные типа значения. Обычно вам нужна изменчивость для таких вещей, как графический интерфейс и узкие места производительности. Мои объекты (использующие NHibernate) также являются изменяемыми (что имеет смысл, поскольку они моделируют данные, хранящиеся в базе данных).
Функции как типы первого класса
Как бы вы это ни называли, передача делегатов, действий или функций - это действительно удобный способ решения целого класса реальных проблем, таких как «дыра в середине». Я также обнаружил, что передача делегата, действия или функции объекту чище, чем когда этот класс объявляет событие и перехватывает это событие (при условии, что обычно есть только один «слушатель»). Когда вы знаете, что есть один прослушиватель, тогда действие обратного вызова может быть передано как параметр конструктора (и сохранено в неизменяемом элементе!)
Возможность составлять функции (например, превращение
Action<T>
в простоAction
) также весьма полезна в некоторых сценариях.Здесь также следует отметить лямбда-синтаксис, потому что вы получаете лямбда-синтаксис только тогда, когда вы продвигаете функции в классы первого класса. Лямбда-синтаксис может быть очень выразительным и лаконичным.
Монады
Правда, это мое слабое место, но я понимаю, что вычислительные рабочие процессы в F #, такие как
async
рабочий процесс, являются монадой. Это тонкий, но очень мощный конструкт. Это так же мощно, какyield
ключевое слово, используемое для созданияIEnumerable
классов в C #. По сути, он строит для вас конечный автомат, но ваша логика выглядит линейной.Ленивая оценка и рекурсия
Я собрал их вместе, потому что, хотя они всегда объединены как функции функционального программирования, они настолько быстро проникли в языки, которые в противном случае были бы императивными, и их уже трудно назвать функциональными.
S-выражение
Думаю, я не уверен, куда это поместить, но способность обрабатывать не скомпилированный код как объект (и проверять / изменять его), такой как Lisp S-Expressions или LINQ Expressions, в некотором смысле самый мощный инструмент функционального программирования. Большинство новых .NET «свободно» интерфейсов и DSL используют комбинацию лямбда-синтаксиса и выражений LINQ для создания очень лаконичных API. Не говоря уже о Linq2Sql / Linq2Nhibernate, где ваш код C # «магическим образом» выполняется как SQL, а не как код C #.
Это был длинный ответ на первую часть вашего вопроса ... сейчас ...
Самой большой ошибкой, с которой я столкнулся, была попытка найти грань между использованием функциональных решений и обязательных решений. Однако, после нескольких попыток обоих подходов, вы начинаете чувствовать, что будет работать лучше.
Если вы знакомы с .NET, я настоятельно рекомендую F #. С другой стороны, если вы более знакомы с JVM, всегда есть Clojure . Если вы более академичны, чем практичны, я бы выбрал Common Lisp или Scheme. Если вы уже знаете Python, я думаю, что там уже есть множество функциональных конструкций.
источник
Это верно, если вы считаете программы, разработанные профессиональными программистами (или, по крайней мере, люди видят себя таковыми). Если вы расширите свою сеть более широко, включив в нее программы, разработанные людьми, которые не считают себя таковыми, FP (или, по крайней мере, программирование в функциональном стиле) будет очень близок к ОО (Excel, Mathematica, Matlab, R ... даже «современный» JavaScript ).
Мое личное мнение таково, что многоядерный процессор не является отличительной чертой FP (по крайней мере, до тех пор, пока компиляторы Haskell, Scala, Clojure, F # не решат проблему локальности кэша). Функция убийца
map
,filter
,fold
и друзья , которые позволяют более лаконичное выражение большой группы алгоритмов. Это усугубляется тем, что языки FP имеют более лаконичный синтаксис, чем большинство популярных аналогов ОО.Кроме того, FP, находящийся ближе к реляционной модели, уменьшает несоответствие импеданса с RDBMS ... что, опять же, по крайней мере для непрограммистов, очень приятно.
Также, когда вам особенно трудно удовлетворить требования «правильности» - в форме, которую сложно протестировать (обычно в научных вычислениях / анализе больших данных, где цель состоит в том, чтобы получить ранее неизвестные и в качестве таких неопределяемых результатов) FP может предложить преимущества.
Сколько ваших проблем может быть решено уже существующими библиотеками / фреймворками на какой платформе (например, JVM или .Net), сколько новых? Существуют ли языковые конструкции, способные выражать эти проблемы напрямую?
Насколько низкоуровневый контроль необходим для пространственно-временной производительности вашего приложения?
Насколько строги ваши требования к «правильности»?
Можете ли вы позволить себе переобучить разработчиков и / или конкурировать с преимуществами, предлагаемыми некоторыми высокодоходными нишами в разработке ПО?
источник
Предполагая, что вы являетесь разработчиком C ++ / C # / Java в промышленности ...
Будьте готовы к сварливым сверстникам, которые не хотят ничего изучать. Будьте готовы к заостренным боссам, навязывающим неправильный выбор языка «потому что когда-то они были кодером». Будьте готовы к содержательным академикам на форумах, покровительствующих вам о моноидах. Будьте готовы к бесконечным языковым войнам, потому что у Scala даже нет устранения хвостовых вызовов, а Clojure действительно требует ножных педалей для всех скобок, и не заводите меня на Erlang.
Если вы веб-программист, то самой большой ошибкой, вероятно, будут ваши волосы.
Я бы начал с платформы:
источник
Для одного (по общему мнению) предвзятого взгляда на этот вопрос вы можете обратиться к блогу Боба Харпера « Existential Type» . Карнеги-Меллон недавно переделал свой учебный план по CS, чтобы сначала преподавать функциональное программирование, а другие парадигмы преподаются только после того, как будет заложено прочное основание в функциональном программировании, и Харпер дает обильный удар, когда новый учебный план внедряется на практике. ,
Харпер является одним из основных разработчиков языка программирования Standard ML, поэтому справедливо сказать, что его собственное мнение по этому вопросу может быть угадано заранее, и он, конечно, не стесняется спорных утверждений в обоснование этой позиции, но он делает его дело хорошо.
источник
var
разу не использовал ни одну изменяемую коллекцию. Итак, императивное мышление - это IMO, своего рода преждевременная оптимизация, которая, как мы все знаем, является корнем всего зла.Не существует волшебной формулы, которая говорит вам, когда следует использовать функциональное программирование. Это не значит, что объектно-ориентированное программирование лучше подходит для наших текущих задач программирования. Это просто еще один способ структурирования программ в терминах другого набора абстракций.
Функциональное программирование не имеет ничего общего с ленью. ML и OCaml - функциональные и строгие языки. Самое большое препятствие, с которым вы столкнетесь, - это структурирование вещей в терминах неизменяемых значений и сведение головы вокруг любой абстракции, используемой в системе типов для побочных эффектов. Функциональные языки лучше подходят для оптимизации из-за того, что они делают явные побочные эффекты в системе типов. Haskell использует монады, но существуют другие подходы к использованию эффектов в чисто функциональных языках. У Clean есть уникальные типы, а у некоторых других языков в разработке есть и другие вещи.
Среди известных мне языков программирования я бы сказал, что только Haskell и Clean можно назвать функциональными языками. Все остальные допускают побочные эффекты, не делая их явными в системе типов. Так что, если вы собираетесь посвятить время изучению функционального программирования, то Haskell, вероятно, единственный, который отвечает всем требованиям. Все остальные, которые я знаю, Erlang, Scala, Clojure и т. Д., Просто предоставляют функциональные абстракции поверх императивного языка. Поэтому, если вы хотите подойти к функциональной парадигме в битах, я бы порекомендовал Scala или Erlang, и если вы хотите заняться всем сразу и, возможно, разочароваться, тогда вам следует пойти на Haskell.
источник
Я бы связал текущий рост интереса к функциональным языкам с тем фактом, что они идеально подходят для параллельных вычислений. Например, вся идея карты-сокращения основана на функциональной парадигме. И нет никаких сомнений в том, что параллельные вычисления будут на подъеме, поскольку ясно, что в настоящее время масштабирование намного проще и дешевле, чем масштабирование. Даже на потребительском рынке процессоры получают больше ядер, а не больше ГГц.
РЕДАКТИРОВАТЬ: так как это не очевидно для всех.
В чистом функциональном программировании функция получает ввод, производит вывод и не имеет побочных эффектов. Отсутствие побочного эффекта означает, что у него нет общего состояния, поэтому нет необходимости в механизмах синхронизации, которые в противном случае были бы необходимы при одновременной работе. Синхронизация - это самая сложная часть любого параллельного / параллельного программного обеспечения, поэтому, делая ее чисто функциональной, вам вообще не приходится иметь дело с самой сложной частью.
Что касается преобразования карты, даже название происходит от функционального программирования (и отображение, и сокращение - типичные операции в функциональной парадигме). Оба шага map-Reduce являются функциями, которые работают параллельно, принимают ввод, производят вывод и не имеют побочных эффектов. Так что это в точности идея чисто функционального программирования.
Несколько примеров FP, используемых для параллелизма:
источник