Блог "Школы программной инженерии"

Что такое функциональное программирование?

Парадигма программирования это подход к конструированию программного обеспечения, основанный на нескольких определяющих принципах. Функциональное программирование это одна из таких парадигм, которая состоит из чистых функций (Pure Function), и позволяет избежать разделяемого состояния (Shared State), изменчивых данных (Mutable Data) и побочных эффектов (Side effect). Функциональное программирование является больше декларативным, чем императивным. Cостояние приложения в функциональном программировании, в отличие от объектно-ориентированного программирования, протекает через чистые функции.

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

Эта статья предоставит фундаментальное понимание функционального программирования и прояснит ряд его преимуществ. Чтобы начать понимать, что такое функциональное программирование, определим основные понятия.

Чистые функции
Первое фундаментальное понятие это чистые функции. Чистые функции задействованы в надежном параллелизме (concurrency), React/Redux приложениях и функциональном программировании. Рассмотрим, что делает функцию «чистой»:
  • чистая функция всегда возвращает одинаковое значение при одинаковых входах;
  •  чистая функция не имеет побочных эффектов.
 Чистые функции полностью независимы от внешнего состояния и, следовательно, невосприимчивы ко многим ошибкам, связанным с разделяемым и изменчивым состоянием. Благодаря этому, чистые функции чрезвычайно легко перемещать. С ними легко делать рефакторинг и реорганизацию кода, что адаптирует программы к будущим изменениям.

Предотвращение разделяемого состояния
Разделяемое состояние (Shared State) это любая переменная, объект или пространство памяти, которые существуют в общей области (shared scope), или свойство объекта, передаваемое между областями. Проблема с разделяемым состоянием состоит в том, что нужно знать всю историю каждой общей переменной, которую функция использует или затрагивает, чтобы понять результат вызова функции. Вторая проблема, связанная с общим состоянием, заключается в том, что изменение порядка вызова функций может вызвать ряд сбоев.
Функциональное программирование избегает разделяемое состояние, используя структуры неизменных данных и чистые вычисления для получения новых данных из уже существующих.

Неизменность
Неизменный объект (immutable object) это объект, который нельзя изменить после его создания. Если вы хотите изменить неизменяемый объект, лучше всего создать новый объект с новым значением. Неизменность это ключевое понятие функционального программирования. Без него теряется история состояний, и ошибки могут проникнуть в ваше программное обеспечение.

Побочные эффекты
Побочный эффект (Side Effect) это любое изменение состояния приложения, которое наблюдается за пределами вызываемой функции, кроме ее возвращаемого значения. Примеры побочных эффектов:
  • изменение любой внешней переменной или свойства объекта;
  • вход в консоль;
  • запись в файл.
Функциональное программирование позволяет избежать побочных эффектов, что облегчает расширение, рефакторинг, отладку, тестирование и обслуживание программы.
Декларативный vs императивный
Функциональное программирование это декларативная парадигма, означающая, что программа выражается через логику решения задачи, без явного описания управления потоком вычислений. Императивный код обычно опирается на операторы, фрагменты кода, которые выполняют какое-то действие. Декларативный код использует выражения , которые представляют собой комбинации вызовов функций, значений и операторов. Другими словами, декларативные программы абстрагируются от процесса управления потоком данных и фокусируются на самом потоке, отвечая на вопросы: что делать; как получить обобщенное решение.
Вывод
Функциональное программирование предпочитает чистые функции вместо разделяемого состояния и побочных эффектов, неизменность вместо изменяемых данных и композицию функций вместо обязательного управления потоком. Функциональное программирование часто легче понять, потому что оно не меняет состояние и зависит только от предусмотренного ввода. По тем же причинам легче тестировать и отлаживать декларативную программу. 

Источник