Функциональное программирование — это парадигма программирования, в которой пытаются связать все без исключения чистыми математическими функциями. Это декларативный тип стиля программирования, который фокусируется на том, что решать, а не на том, как решать (нацеленный на императивный стиль программирования).
Clojure, Common Lisp, Erlang, Haskell и Scala — одни из самых известных языков программирования, следующих за подходом функционального программирования. Парадигма программирования основана на лямбда-исчислении, которое кратко объясняется ниже:
Лямбда-исчисление
Вместо утверждений он использует выражения. В отличие от оператора, который выполняется для присвоения переменных, вычисление выражения дает значение. Лямбда-исчисление составляет основу почти всех используемых языков функционального программирования.
Лямбда-исчисление, разработанное Алонзо Черчем, представляет собой основу для изучения вычислений с функциями. Все, что вычислимо с использованием лямбда-исчисления, вычислимо. Удивительно, но его можно назвать самым емким языком программирования из всех.
По своим вычислительным возможностям лямбда-исчисление похоже на машину Тьюринга, заложившую основу императивного стиля программирования. Проще говоря, лямбда-исчисление представляет собой теоретическую основу, описывающую функции и их оценку.
Функциональное программирование: концепции
Есть 5 самых важных понятий.
Чистые функции
Чистые функции обладают двумя важными свойствами:
- Всегда производите один и тот же результат с одними и теми же аргументами, не обращая внимания на другие факторы. Это свойство также известно как неизменность.
- Детерминированы. Чистые функции либо дают какой-то вывод, либо изменяют любой аргумент или глобальные переменные, т.е. у них нет побочных эффектов.
Поскольку чистые функции не имеют побочных эффектов или скрытого ввода-вывода, программы, построенные с использованием функциональной парадигмы, легко отлаживать. Более того, чистые функции упрощают написание параллельных приложений.
Когда код написан с использованием стиля функционального программирования, соответствующий компилятор может:
- Запомни результаты
- Распараллеливайте инструкции
- Дождитесь оценки результатов
Рекурсия
В парадигме функционального программирования нет циклов for и while. Вместо этого языки функционального программирования полагаются на рекурсию для итерации. Рекурсия реализуется с помощью рекурсивных функций, которые повторно вызывают себя до тех пор, пока не будет достигнут базовый вариант.
Ссылочная прозрачность
Переменным, однажды определенным на функциональном языке программирования, не разрешается изменять значение, которое они хранят, на протяжении всего выполнения программы. Это известно как ссылочная прозрачность. Это гарантирует, что одно и то же языковое выражение дает одинаковый результат.
В функциональных программах нет операторов присваивания. Для сохранения дополнительных значений в программе, разработанной с использованием функционального программирования, необходимо определить новые переменные. Состояние переменной в такой программе постоянно в любой момент времени.
Ссылочная прозрачность устраняет даже малейшие шансы каких-либо нежелательных эффектов из-за того, что любая переменная может быть заменена ее фактическим значением в любой момент выполнения программы.
Функции являются первоклассными и могут быть более высокого порядка
Функции в стиле функционального программирования рассматриваются как переменные. Следовательно, они являются первоклассными функциями. Эти первоклассные функции могут быть переданы другим функциям в качестве параметров, возвращены из функций или сохранены в структурах данных.
Функция высшего порядка — это функция, которая принимает другие функции в качестве аргументов и / или возвращает функции. Функции первого класса могут быть функциями высшего порядка в языках функционального программирования.
Переменные неизменяемы
Переменные неизменяемы, т. Е. Невозможно изменить переменную после ее инициализации. Хотя мы можем создать новую переменную, изменение существующих переменных запрещено.
Неизменяемость переменных в функциональном языке программирования дает преимущества в виде сохранения состояния на протяжении всего выполнения программы.
Преимущества
- Поскольку чистые функции не изменяют никаких состояний и полностью зависят от ввода, их легко понять. Возвращаемое значение, предоставляемое такими функциями, совпадает с выводом, произведенным ими. Аргументы и тип возвращаемого значения чистых функций выдаются их сигнатурой функции.
- Из-за природы чистых функций, позволяющих избежать изменения переменных или каких-либо данных за ее пределами, реализация параллелизма становится эффективной.
- Он поддерживает концепцию ленивого вычисления, что означает, что значение оценивается и сохраняется только тогда, когда оно требуется.
- Чистые функции принимают аргументы один раз и выдают неизменяемый результат. Следовательно, они не производят скрытого вывода. Они используют неизменяемые значения, что упрощает отладку и тестирование.
- Этот стиль рассматривает функции как значения и передает то же самое другим функциям как параметры. Это улучшает понимание и читаемость кода.
Недостатки
- Неизменяемые значения в сочетании с рекурсией могут привести к снижению производительности
- В некоторых случаях написание чистых функций приводит к снижению читабельности кода.
- Хотя писать чистые функции легко, объединить их с остальной частью приложения, а также с операциями ввода-вывода сложно.
- Написание программ в рекурсивном стиле вместо использования для них циклов может быть сложной задачей.
Приложения
Часто языки функционального программирования предпочитают использовать в академических целях, а не для разработки коммерческого программного обеспечения.
Тем не менее, несколько известных языков программирования, следующих парадигме функционального программирования, таких как Clojure, Erlang, F #, Haskell и Racket, широко используются для разработки множества коммерческих и промышленных приложений.
WhatsApp использует Erlang, язык программирования, следующий парадигме функционального программирования, чтобы позволить более чем 100 сотрудникам управлять данными, принадлежащими более чем 1,5 миллиардам человек.
Еще один важный знаменосец стиля функционального программирования — Haskell . Он используется Facebook в своей системе защиты от спама. Даже JavaScript, один из наиболее широко используемых языков программирования, демонстрирует свойства динамически типизированного функционального языка.
Более того, функциональный стиль программирования необходим для того, чтобы различные языки программирования занимали лидирующие позиции в разных областях. Например, R в статистике и J, K и Q в финансовом анализе.
Некоторые элементы этой парадигмы программирования даже используются предметно-ориентированными декларативными языками, такими как Lex / Yacc и SQL, для исключения изменяемых значений.
Как правило, эта парадигма широко применяется в:
- Приложения, нацеленные на параллелизм или параллелизм
- Проведение математических вычислений
Резюме
Помимо чисто функциональных языков программирования, можно установить функциональный подход к программированию и на нефункциональных языках программирования. Есть несколько книг по этой теме.
В C++ 11, C# 3.0 и Java 8 добавлены конструкции для облегчения стиля функционального программирования. Одним из наиболее ярких примеров императивного языка программирования, использующего функциональный стиль программирования, является язык программирования Scala .
Хотя Scala обычно написана в функциональном стиле, в ней присутствуют побочные эффекты и изменяемые состояния. Следовательно, язык программирования можно поместить в промежуточное состояние между императивным и функциональным стилями программирования.