что это такое простыми словами, где применяется и что значит – SkillFactory
Содержание
👉 В этом разделе мы на примерах разбираем сложные айтишные термины. Если вы хотите почитать вдохновляющие и честные истории о карьере в IT, переходите в другие разделы.
Функциональные языки программирования — это языки, в которых процессы представлены как функции в математическом понимании этого слова. То есть функция в них определяется не как подпрограмма, а как соответствие между множествами.
Такой подход к программированию называют функциональным. Название не значит, что код основан на функциях: это справедливо почти для любого языка. Функциональность определяется именно подходом: весь код описывается как правила работы с информацией, и они могут исполняться в любом порядке.
Функциональный подход — противоположность императивному, в котором программист задает программе четкий порядок действий по шагам. Тут все сложнее: программа сама решает, как и в каком порядке исполнять действия, а программист описывает правила взаимодействия и связи между компонентами.
Сейчас программисты чаще всего работают с ООП — объектно-ориентированным программированием. Функциональный подход используют реже: он сложнее и применим не ко всем задачам. Но сейчас его популярность растет, и тому есть причины: чистота кода, надежность программ, высокие возможности для оптимизации.
Благодаря своим особенностям функциональное программирование распространено при работе с важными данными или при решении задач, где нужны сложные вычисления. Есть фреймворки, с которыми проще работать в функциональном стиле, а есть такие, в которых сочетаются оба подхода. Как пример — React и Redux для JavaScript.
Сейчас программисты придерживаются такого подхода:
Посмотреть программу
Условно можно выделить две группы. Первая — языки, жестко ориентированные на функциональное программирование. Вторая — так называемые мультипарадигменные языки, то есть такие, на которых можно писать по-разному. В том числе в функциональном стиле.
К функциональным языкам относятся Haskell, F#, OCaml, ELM, серия языков Lisp, а также Erlang и его потомок Elixir. Иногда сюда же относят Scala и Nemerle, хотя эти языки дают возможность программировать и в функциональном, и в императивном стилях. Они старые и сейчас применяются не так часто, как большинство современных.
Еще к этой группе относится несколько узкоспециализированных языков: язык вычислительной платформы Wolfram, языки J и K для финансового анализа, язык R для статистических целей. На функциональном языке APL базируется язык научной математической среды MATLAB. Также сюда можно отнести языки, которые используются при работе с электронными таблицами, а еще, частично, SQL — язык запросов для работы с базами данных.
К мультипарадигменным языкам, на которых можно писать в функциональном стиле, относятся уже упомянутые Scala и Nemerle, а также Go, JavaScript и некоторые его фреймворки. В меньшей степени сюда же можно отнести Python, Ruby, PHP и C++, а также Java: они больше ориентированы на ООП, но в них есть и функциональные элементы.
Разница между функциональным и императивным подходомЧтобы лучше понять, как это работает, воспользуемся аналогией.
- Императивная парадигма похожа на правила умножения в столбик. Последовательность действий, их порядок и тип четко определены. Мы выполняем команды, которые кто-то придумал до нас, как по инструкции.
- Функциональная парадигма — это, скорее, правила орфографии и пунктуации. Нет четкой последовательности, как именно их применять. Правила нельзя представить как строгую инструкцию. Вместо этого мы сами решаем, какое правило в какой ситуации будет актуально. И последовательность, в которой мы это делаем, не имеет значения.
Объектно-ориентированное программирование отличается от функциональной парадигмы. В нем все представлено в виде объектов, в функциональном — в виде функций. ООП смешивает данные и поведение, функциональный подход — разделяет. Различаются особенности работы с информацией, структура программ и многое другое.
ООП в целом относится скорее к императивному типу программирования: код — это набор команд, рассказывающих компьютеру, что делать. Но «чистым» императивным программированием его назвать сложно — скорее, дополненным и измененным.
Сложность изучения функциональных языковО функциональном программировании можно услышать, что оно сложно в освоении. Но тут есть парадокс, о котором говорят некоторые программисты: новичку понять его принципы может быть легче, чем разработчику с опытом программирования в ООП. Это связано с тем, что разработчики в императивных стилях уже привыкли к определенному типу логики, а перестроиться на что-то принципиально новое сложнее, чем изучать с нуля.
Сейчас считается, что хороший разработчик должен разбираться в обеих парадигмах и знать, когда лучше применять одну, а когда — другую.
Особенности функционального подходаФункциональное программирование определяется несколькими важными правилами. Это основы, которые нужно знать, чтобы представлять, как в принципе работает парадигма.
Отсутствие жесткой последовательности. Об этом мы уже говорили. Разработчик задает правила, а компилятор кода сам решает, в какой последовательности их выполнять. Жесткий порядок действий программист не задает. Его выбирает сама программа.
«Чистые» функции. Чистые функции — это такие, которые удовлетворяют двум условиям:
- при одинаковых входных данных функция всегда вернет одинаковый результат.
- когда функция выполняется, не возникают побочные эффекты — так называют действия, которые влияют на что-то за ее пределами. Например, изменение переменной, чтение данных или вывод в консоль — это побочные эффекты.
В функциональном программировании все функции должны быть чистыми. Кажется, будто это сложно и ограничивает разработчика, но на самом деле при грамотном подходе такое даже расширяет возможности. Ведь чистые функции можно запускать, не боясь, что они что-то изменят или нарушат.
Неизменные переменные. В функциональном программировании нет переменных в привычном виде. В нем все объявленные переменные неизменны — то есть фактически это константы. Если с какой-то переменной нужно провести вычисления, она не изменяется: создается новая переменная, и результат вычислений записывается в нее. А исходная остается прежней — ее значение не меняется.
«Первоклассные» функции высшего порядка. Все функции в функциональном программировании должны быть первого класса и высшего порядка. Сейчас объясним, что это значит.
- Функция первого класса — это такая, которую можно представить как переменную. То есть, ее можно передавать как аргумент другим функциям, возвращать как результат работы других функций, сохранять в переменную или структуру данных.
- Функция высшего порядка — такая, которая принимает в качестве аргументов функции или возвращает их в качестве результата.
Возможность работы с такими функциями есть не только в функциональном программировании. Более того, такое требование есть не только в нем. Но для него такой подход обязателен — вместе с другими особенностями.
Относительная прозрачность.
Это не означает, что функция должна выдавать одинаковый результат во всех случаях — только при одинаковых входных данных. Про это также говорит часть определения чистой функции.
Рекурсия вместо циклов. В классическом функциональном программировании циклы реализованы как рекурсия. Стоит понимать разницу:
- цикл — несколько выполнений одной и той же части кода подряд;
- рекурсия — явление, когда функция вызывает сама себя, но с другими аргументами.
Очень многие алгоритмы в функциональном подходе построены на рекурсии — функциях, вызывающих себя. Так реализованы многие действия, где что-то нужно выполнить несколько раз.
Лямбда-исчисление. Это особая математическая система, которая используется в функциональных языках программирования. Ее название также иногда пишут как λ-исчисление. Мы не будем углубляться в сложные математические понятия и выделим только несколько особенностей, важных для понимания функционального программирования:
- в λ-исчислении есть две основных операции — аппликация и абстракция. Первое — это, по сути, вызов функции к заданному значению. Второе — построение функции по имеющимся выражениям;
- все функции могут быть анонимными и складываться только из списка аргументов. Анонимные функции — это такие, у которых нет уникального имени, а объявляются они в месте выполнения;
- при вызове функции с несколькими аргументами происходит ее каррирование — преобразование в несколько функций, в каждой из которых один аргумент. То есть, функция вида f(a, b, c) превратится в набор функций f(a)(b)(c). Результатом f(a) будет функция, которая тут же применится к аргументу b.
Чистота кода. Код, написанный на функциональном языке, выглядит чистым и понятным. Сюда же можно отнести локальную читаемость — можно разобраться, как работает та или иная функция, без строгой привязки к остальному коду. Код более чистый еще и за счет отсутствия четкой последовательности: чтобы понять происходящее в нем, не обязательно знать порядок выполнения разных действий.
Надежность. Благодаря тому, что функции чистые и не изменяют окружение вокруг себя, функциональный код более надежен. Если в одной конкретной функции что-то сломается, это не повлечет за собой проблемы с другими компонентами. Не нужно отслеживать побочные эффекты — согласно определению чистой функции их быть просто не должно. Правда, на практике это не всегда возможно, но эту деталь мы подробнее обсудим ниже.
Оптимизация. Когда компилятор обрабатывает функциональную программу, он сам решает, в каком порядке вызывать функции. За счет этого программы легче оптимизировать: такой подход открывает широкие возможности для автоматической оптимизации на уровне компилятора. Оптимизация означает, что код будет быстрее или производительнее.
Удобное тестирование. Благодаря все тем же чистым функциям этот стиль программирования удобнее отлаживать и тестировать. Особенно это заметно при модульном тестировании — таком, где каждый компонент проверяется по отдельности. Ведь если мы проверяем функцию, которая не изменяет ничего снаружи — значит, нам не нужно дополнительно думать о тестировании возможных побочных эффектов.
Распараллеливание вычислений. За счет отсутствия жесткой последовательности функциональное программирование отлично подходит для параллельных вычислений — одновременного выполнения нескольких действий. С императивным подходом их сложнее организовать, кроме того, нужно учитывать побочные эффекты. А функциональное программирование гарантирует, что вызов одной функции не повлияет на вызов другой — поэтому снижается риск ошибок и конфликтов при параллельных вычислениях.
Гибкая работа с функциями. Благодаря гибкой и сложной работе с функциями некоторые действия можно выполнять быстрее и удобнее, чем с императивным подходом. Это мощный инструмент, особенно для решения специфических задач: математических, научных, связанных с точными вычислениями или подобными сферами. Популярность подхода при решении таких задач видно и на практике: языки для математических, научных, экономических или статистических расчетов — по большей части функциональные.
Использование большого объема памяти. Этот минус вытекает из тех же особенностей, что и преимущества. Многие действия построены на рекурсии, а при изменении любого значения создается новая переменная — поэтому программа начинает требовать больше памяти, чем императивная с классическими циклами и изменяемыми значениями. Это значит, что для эффективной работы в языке должен быть мощный сборщик мусора или удобные инструменты для ручной работы с памятью. За ней нужно следить, иначе есть риск серьезного снижения производительности.
Непредсказуемый порядок действий. Эта особенность функционального программирования — плюс и минус одновременно. О плюсах мы уже говорили выше. Минус в том, что для некоторых важных задач порядок действий важен по определению. Например, ввод и вывод. Если данные будут вводиться или выводиться хаотично, в непредсказуемом порядке, это ухудшит работу программы. Поэтому часто функциональное программирование комбинируют с императивным — для большей гибкости и производительности кода в целом.
Неуниверсальность чистых функций. Одними чистыми функциями не получится решить многие задачи. Некоторые важные действия по определению сложно или невозможно реализовать через чистые функции. Поэтому программистам приходится прибегать к дополнительным ухищрениям и усложнять код, чтобы избежать этого минуса. Также некоторые функции на практике оказываются не совсем чистыми — тут опять же приходится обходить ограничения и придумывать новые способы.
Как начать программировать в функциональном стилеСначала вам понадобится познакомиться с основами парадигмы и с теорией. Можно скомбинировать это с началом изучения функциональных языков, чтобы сразу «пощупать» подход на практике. Но помните, что многие решения сначала могут показаться вам неочевидными — к особым принципам нужно привыкнуть. Тем не менее, функциональное программирование – мощный и интересный инструмент, и изучить его вполне реально даже новичку.
Что такое функциональное программирование — Журнал «Код» программирование без снобизма
В программировании есть два больших подхода — императивное и функциональное. Они существенно отличаются логикой работы, ещё и создают путаницу в названиях. Сейчас объясним.
🤔 Функциональное — это про функции?
❌ Нет. Функциональное — это не про функции. Функции есть почти в любых языках программирования: и в функциональных, и в императивных. Отличие функционального программирования от императивного — в общем подходе.
Метафора: инструкция или книга правил
Представьте, что вы открываете кафе-столовую. Сейчас у вас там два типа сотрудников: повара и администраторы.
Для поваров вы пишете чёткие пошаговые инструкции для каждого блюда. Например:
- Налить воды в кастрюлю
- Поставить кастрюлю с водой на огонь
- Добавить в кастрюлю с водой столько-то соли
- Если нужно приготовить 10 порций, взять одну свёклу. Если нужно приготовить 20 порций, взять две свёклы.
- Почистить всю свёклу, которую вы взяли
- …
Повар должен следовать этим инструкциям ровно в той последовательности, в которой вы их написали. Нельзя сначала почистить свёклу, а потом взять её. Нельзя посолить кастрюлю, в которой нет воды. Порядок действий важен и определяется вами. Это пример императивного программирования. Вы повелеваете исполнителем. Можно сказать, что исполнители выполняют ваши задания.
Для администратора вы пишете не инструкцию, а как бы книгу правил:
- У нас нельзя со своим. Если гости пришли со своим, то сделать им замечание такое-то.
- В зале должно быть чисто. Если в зале грязно, вызвать уборщика.
- Если образовалась очередь, открыть дополнительную кассу.
Это тоже команды, но исполнять их администратор будет не в этой последовательности, а в любой на своё усмотрение. Можно сказать, что задача этого человека — исполнять функции администратора, и мы описали правила, по которым эти функции исполнять. Это пример функционального программирования.
❌ Программисты, не бомбите
Конечно же, это упрощено для понимания. Вы сами попробуйте это нормально объяснить (можно прямо в комментах).
Императивное программирование
Примеры языков: C, С++, Go, Pascal, Java, Python, Ruby
Императивное программирование устроено так:
В языке есть команды, которые этот язык может выполнять. Эти команды можно собрать в подпрограммы, чтобы автоматизировать некоторые однотипные вычисления. В каком порядке записаны команды внутри подпрограммы, в том же порядке они и будут выполняться.
Есть переменные, которые могут хранить данные и изменяться во время работы программы. Переменная — это ячейка для данных. Мы можем создать переменную нужного нам типа, положить туда какое-то значение, а потом поменять его на другое.
Как называть переменные и функции, чтобы вас уважали бывалые программисты
Если подпрограмме на вход подать какое-то значение, то результат будет зависеть не только от исходных данных, но и от других переменных. Например, у нас есть функция, которая возвращает размер скидки при покупке в онлайн-магазине. Мы добавляем в корзину товар стоимостью 1000 ₽, а функция должна нам вернуть размер получившейся скидки. Но если скидка зависит от дня недели, то функция сначала проверит, какой сегодня день, потом посмотрит по таблице, какая сегодня скидка.
Получается, что в разные дни функция получает на вход 1000 ₽, но возвращает разные значения — так работает императивное программирование, когда всё зависит от других переменных.
Последовательность выполнения подпрограмм регулируется программистом. Он задаёт нужные условия, по которым движется программа. Вся логика полностью продумывается программистом — как он скажет, так и будет. Это значит, что разработчик может точно предсказать, в какой момент какой кусок кода выполнится — код получается предсказуемым, с понятной логикой работы.
Если у нас код, который считает скидку, должен вызываться только при финальном оформлении заказа, то он выполнится именно в этот момент. Он не посчитает скидку заранее и не пропустит момент оформления.
👉 Суть императивного программирования в том, что программист описывает чёткие шаги, которые должны привести код к нужной цели.
Звучит логично, и большинство программистов привыкли именно к такому поведению кода. Но функциональное программирование работает совершенно иначе.
Функциональное программирование
Примеры языков: Haskell, Lisp, Erlang, Clojure, F#
Смысл функционального программирования в том, что мы задаём не последовательность нужных нам команд, а описываем взаимодействие между ними и подпрограммами. Это похоже на то, как работают объекты в объектно-ориентированном программировании, только здесь это реализуется на уровне всей программы.
Например, в ООП нужно задать объекты и правила их взаимодействия между собой, но также можно и написать просто код, который не привязан к объектам. Он как бы стоит в стороне и влияет на работу программы в целом — отправляет одни объекты взаимодействовать с другими, обрабатывает какие-то результаты и так далее.
Функциональное программирование здесь идёт ещё дальше. В нём весь код — это правила работы с данными. Вы просто задаёте нужные правила, а код сам разбирается, как их применять.
Если мы сравним принципы функционального подхода с императивным, то единственное, что совпадёт, — и там, и там есть команды, которые язык может выполнять. Всё остальное — разное.
Команды можно собирать в подпрограммы, но их последовательность не имеет значения. Нет разницы, в каком порядке вы напишете подпрограммы — это же просто правила, а правила применяются тогда, когда нужно, а не когда про них сказали.
Переменных нет. Вернее, они есть, но не в том виде, к которому мы привыкли. В функциональном языке мы можем объявить переменную только один раз, и после этого значение переменной измениться не может. Это как константы — записали и всё, теперь можно только прочитать. Сами же промежуточные результаты хранятся в функциях — обратившись к нужной, вы всегда получите искомый результат.
Функции всегда возвращают одно и то же значение, если на вход поступают одни и те же данные. Если в прошлом примере мы отдавали в функцию сумму в 1000 ₽, а на выходе получали скидку в зависимости от дня недели, то в функциональном программировании если функция получит в качестве параметра 1000 ₽, то она всегда вернёт одну и ту же скидку независимо от других переменных.
Можно провести аналогию с математикой и синусами: синус 90 градусов всегда равен единице, в какой бы момент мы его ни посчитали или какие бы углы у нас ещё ни были в задаче. То же самое и здесь — всё предсказуемо и зависит только от входных параметров.
Последовательность выполнения подпрограмм определяет сам код и компилятор, а не программист. Каждая команда — это какое-то правило, поэтому нет разницы, когда мы запишем это правило, в начале или в конце кода. Главное, чтобы у нас это правило было, а компилятор сам разберётся, в какой момент его применять.
В русском языке всё работает точно так же: есть правила правописания и грамматики. Нам неважно, в каком порядке мы их изучили, главное — чтобы мы их вовремя применяли при написании текста или в устной речи. Например, мы можем сначала пройти правило «жи-ши», а потом правило про «не с глаголами», но применять мы их будем в том порядке, какой требуется в тексте.
👉 Получается, что смысл функционального программирования в том, чтобы описать не сами чёткие шаги к цели, а правила, по которым компилятор сам должен дойти до нужного результата.
Что такое функциональное программирование? Учебник с примером
Автор: Мэтью Мартин
ЧасыОбновлено
Что такое функциональное программирование?
Функциональное программирование (также называемое FP) — это способ мышления о создании программного обеспечения путем создания чистых функций. Он избегает концепций общего состояния, изменяемых данных, наблюдаемых в объектно-ориентированном программировании.
Функциональные языки делают акцент на выражениях и объявлениях, а не на выполнении операторов. Следовательно, в отличие от других процедур, которые зависят от локального или глобального состояния, вывод значения в FP зависит только от аргументов, переданных функции.
В этом уроке вы узнаете-
- Что такое функциональное программирование?
- Характеристики функционального программирования
- История функционального программирования
- Функциональные языки программирования
- Базовая терминология и концепции функционального программирования
- Преимущества функционального программирования
- Ограничения функционального программирования
- Функциональное программирование против объектно-ориентированного программирования
Характеристики функционального программирования
- Метод функционального программирования фокусируется на результатах, а не на процессе
- Акцент делается на том, что должно быть вычислено
- Данные неизменны
- Функциональное программирование Разложить задачу на «функции»
- Он построен на концепции математических функций, которые используют условные выражения и рекурсию для выполнения вычислений
- Не поддерживает итерацию, такую как операторы цикла и условные операторы, такие как If-Else
История функционального программирования
- Основой функционального программирования является лямбда-исчисление. Он был разработан в 1930-х годах для функционального приложения, определения и рекурсии .
- LISP был первым функциональным языком программирования. Маккарти разработал его в 1960 году .
- В конце 70-х годов исследователи из Эдинбургского университета определили ML (мета-язык) .
- В начале 80-х в язык Hope были добавлены алгебраические типы данных для рекурсии и рассуждений по уравнениям
- В 2004 году Инновация функционального языка «Scala».
Языки функционального программирования
Целью любого языка FP является имитация математических функций. Однако основной процесс вычислений в функциональном программировании отличается.
Вот некоторые наиболее известные языки функционального программирования:
- Haskell
- СМЛ
- Кложур
- Скала
- Эрланг
- Чистый
- F#
- ML/OCaml Lisp/схема
- XSLT
- SQL
- Математика
Базовая терминология и понятия функционального программирования
Неизменяемые данные
Неизменяемые данные означают, что вы должны легко создавать структуры данных вместо изменения уже существующих.
Ссылочная прозрачность
Функциональные программы должны выполнять операции так, как если бы это было в первый раз. Таким образом, вы будете знать, что могло или не могло произойти во время выполнения программы, и его побочные эффекты. В терминах ФП это называется ссылочной прозрачностью.
Модульность
Модульная конструкция повышает производительность. Небольшие модули могут быть написаны быстро и имеют больше шансов на повторное использование, что, безусловно, приводит к более быстрой разработке программ. Кроме того, модули можно тестировать отдельно, что помогает сократить время, затрачиваемое на модульное тестирование и отладку.
Ремонтопригодность
Ремонтопригодность — это простой термин, который означает, что программирование FP легче поддерживать, поскольку вам не нужно беспокоиться о случайном изменении чего-либо за пределами данной функции.
Функция первого класса
«Функция первого класса» — это определение, относящееся к сущностям языка программирования, которые не имеют ограничений на их использование. Поэтому первоклассные функции могут появляться в любом месте программы.
Закрытие
Закрытие — это внутренняя функция, которая может обращаться к переменным родительской функции даже после выполнения родительской функции.
Функции высшего порядка
Функции высшего порядка либо принимают другие функции в качестве аргументов, либо возвращают их в качестве результатов.
Функции высшего порядка допускают частичное применение или каррирование. Этот метод применяет функцию к своим аргументам по одному, так как каждое приложение возвращает новую функцию, которая принимает следующий аргумент.
Чистая функция
«Чистая функция» — это функция, входы которой объявлены как входы, и ни один из них не должен быть скрыт. Выходы также объявляются как выходы.
Чистые функции действуют на свои параметры. Это неэффективно, если ничего не возвращается. Более того, он предлагает тот же результат для заданных параметров
Пример:
Функция Pure(a,b) { вернуть а+б; }
Нечистые функции
Нечистые функции прямо противоположны чистым. У них есть скрытые входы или выходы; это называется нечистым. Нечистые функции нельзя использовать или тестировать изолированно, поскольку они имеют зависимости.
Пример
int z; функция нечистая () { г = г+10; }
Композиция функций
Композиция функций — это объединение двух или более функций для создания новой.
Общие состояния
Общие состояния — важная концепция в ООП-программировании. По сути, это добавление свойств к объектам. Например, если жесткий диск является объектом, в качестве свойств можно добавить емкость хранилища и размер диска.
Побочные эффекты
Побочные эффекты — это любые изменения состояния, происходящие вне вызываемой функции. Самая большая цель любого языка программирования FP — свести к минимуму побочные эффекты, отделив их от остального программного кода. В программировании FP жизненно важно убрать побочные эффекты из остальной логики вашего программирования.
Преимущества функционального программирования
- Позволяет избежать путаницы и ошибок в коде
- Легче тестировать и выполнять модульное тестирование и отлаживать код FP.
- Параллельная обработка и параллелизм
- Развертывание горячего кода и отказоустойчивость
- Предлагает лучшую модульность с более коротким кодом
- Повышение производительности разработчика
- Поддерживает вложенные функции
- Функциональные конструкции, такие как ленивые карты и списки и т. д.
- Позволяет эффективно использовать лямбда-исчисление
Ограничения функционального программирования
- Парадигма функционального программирования непроста, поэтому ее трудно понять новичку
- Трудно поддерживать, так как многие объекты развиваются во время кодирования
- Требуется много насмешек и обширная настройка окружения
- Повторное использование очень сложно и требует постоянного рефакторинга
- Объекты могут неправильно отображать проблему
Функциональное программирование и объектно-ориентированное программирование
Функциональное программирование | ООП |
---|---|
FP использует неизменяемые данные. | ООП использует изменяемые данные. |
Следует модели на основе декларативного программирования. | следует императивной модели программирования. |
Основное внимание уделяется: «Что вы делаете. в программе». | Основное внимание в нем уделяется тому, «как вы программируете». |
Поддерживает параллельное программирование. | Нет поддержки для параллельного программирования. |
Его функции не имеют побочных эффектов. | Методможет иметь множество побочных эффектов. |
Управление потоком выполняется с использованием вызовов функций и вызовов функций с рекурсией. | Процесс управления потоком выполняется с использованием циклов и условных операторов. |
Порядок выполнения операторов не очень важен. | Порядок выполнения операторов важен. |
Поддерживает как «Абстракцию над данными», так и «Абстракцию над поведением». | Поддерживает только «Абстракцию над данными». |
Заключение
- Функциональное программирование или FP — это способ мышления о создании программного обеспечения, основанный на некоторых фундаментальных определяющих принципах
- Концепции функционального программирования фокусируются на результатах, а не на процессе
- Целью любого языка FP является имитация математических функций
- Некоторые наиболее известные языки функционального программирования: 1) Haskell 2) SM 3) Clojure 4) Scala 5) Erlang 6) Clean
- «Чистая функция» — это функция, входы которой объявлены как входы, и ни один из них не должен быть скрыт. Выходы также объявляются как выходы.
- Immutable Data означает, что вы должны легко создавать структуры данных вместо изменения уже существующих
- Позволяет избежать запутанных проблем и ошибок в коде
- Функциональный код непрост, поэтому его сложно понять новичку
- FP использует неизменяемые данные, в то время как OOP использует изменяемые данные
Функциональное программирование против ООП: какую парадигму использовать
Функциональное программирование сосредоточено вокруг создания программного обеспечения, состоящего из функций, подобных процедурному программированию; однако есть тонкие различия. Мы выделяем эти различия, обсуждая ключевые концепции функционального программирования ниже.
Граждане первого класса
Функции рассматриваются как примитивы. Примитивы служат простейшими элементами языка программирования. Таким образом, функция может быть:
- сохраненной в переменной
- передается в качестве аргумента
- возвращено из функции
Поскольку у них есть эти возможности, функции называются первоклассными гражданами . Термин «гражданин первого класса» по существу обозначает элемент, который поддерживает все остальные общедоступные операции.
Чистые функции
Цель функционального программирования — по возможности писать чистые функции.
Чистая функция не изменяет глобальное состояние программы и поэтому считается, что не имеет побочных эффектов . Вместо этого его возвращаемое значение основано исключительно на его входных параметрах.
Чистые функции позволяют проводить многочисленные оптимизации компилятора, что приводит к значительному сокращению времени выполнения программы. Кроме того, чистые функции идеально подходят для модульного тестирования. Мы можем проводить модульное тестирование чистой функции изолированно, не беспокоясь о том, где в коде она будет использоваться.
Функции высшего порядка и рекурсия
Вместо конструкций итеративного цикла, таких как для
и , а
, в функциональном программировании мы используем функции высшего порядка и хвостовых вызовов для рекурсивного цикла.
Функция высшего порядка принимает функцию в качестве входных данных, выполняет операцию над входной функцией и впоследствии возвращает функцию.
Хвостовой вызов относится к вызову функции в конце функции. Вызов хвоста может привести к рекурсивному циклу, когда функция вызывает сама себя. Многие компиляторы выполняют Оптимизация хвостового вызова (он же Устранение хвостового вызова ), что делает рекурсию такой же быстрой, как итерационные циклы.
Ключевые причины предпочтения рекурсии по сравнению с обычными примитивными циклами:
- простота кода
- избегать изменяемых объектов , чтобы сделать код более надежным
Неизменность
Неизменяемость — это постоянство переменной после присвоения ей данных.
Никакое значение, присвоенное переменной в функциональном программировании, не может быть изменено; единственный способ изменить значение — создать новую переменную. Именно неизменность позволяет функциональному программированию использовать чистые функции. Эти функции не изменяют свои входные данные и не полагаются ни на что, кроме входных данных, для достижения результатов. В этом функциональное программирование похоже на математику.