Функциональное программирование (ФП) существует уже на протяжении последних шести десятилетий, и на данный момент не прекращает попыток преодолеть повсеместное доминирование объектно-ориентированного программирования (ООП). В связи со стремительным ростом машинного обучения (МО) и больших данных ФП стало набирать популярность из-за простоты распараллеливания чистых функций. Функциональная парадигма также упрощает отслеживание, тестирование и обслуживание кода для задач анализа данных и рабочих процессов, что создает предпосылки для ее активного использования в ближайшем будущем. 

Даже такие языки ООП, как Java и Python, позаимствовали грандиозные концепции ФП в виде встроенных функций map(), filter() и reduce(). Помимо этого, у них есть возможность объявлять чистые однострочные лямбда-функции, а также создавать функции первого класса и высшего порядка для передачи их в другие функции в качестве параметров. 

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

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

В связи с этим, давайте выясним, почему разработчики ПО влюбляются в ФП и рассматривают его как неотъемлемую часть компьютерной науки будущего. Кроме того, проанализируем ряд особенностей ООП и посмотрим, сможет ли ФП полностью их заменить. Хотя забегая вперед, можно с уверенностью сказать, что обе парадигмы будут сосуществовать не только в разработке ПО, но даже в одном приложении. 

Применение чистых функций 

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

Как правило, чистые функции заимствуют математические методы решения задач. Например, если набрать на калькуляторе 3+3, то в результате получим 6. Здесь не используются внешние элементы, что гарантирует чистоту функциональных программ. Примером может служить однострочная лямбда-функция, принимающая на вход n и возвращающая n + n. 

Отладка  —  извечная проблема и для программистов, и для разработчиков, в связи с чем они переходят на ФП, поскольку чистые функции упрощают отладку. 

Оптимальная прозрачность 

Благодаря чистым функциям ФП становится абсолютно прозрачным. Кроме того, они работают исключительно без участия внешних элементов. Это означает, что они оперируют только входными данными пользователя. И наоборот, нефункциональные языки привлекают дополнительные входные значения и возвращают результаты, несколько отличающиеся от информации пользователя.

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

Повышение читаемости 

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

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

Статические переменные 

В обычном понимании “переменная” представляет из себя нечто, переходящее из одного состояния в другое. Однако в ФП у нее абсолютно другое значение. 

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

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

Руководствуясь именно этим критерием, многие разработчики переключились на ФП, чтобы повысить безопасность своих систем. 

Удобное параллельное программирование 

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

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

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

Проверка сигнатур функций 

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

Кроме того, есть еще одна практическая причина, по которой будущее разработки ПО связывают именно с ФП. 

Scala, будучи языком ФП, позволяет разработчикам писать код, применяя обе парадигмы: ООП и ФП. В основном он ориентирован на создание ПО с помощью исключительно чистых функций и постоянных значений. Постепенно этот язык становится полностью функциональным. 

Причины, по которым ФП не заменит ООП 

ООП стало важным компонентом разработки ПО. Несмотря на существование таких языков, как например C++ и Java, разработчики, нацеленные на создание мобильного ПО, должны освоить объектно-ориентированный подход. Он же применим и к сложным веб-разработкам, учитывая востребованность таких языков ООП, как PHP и Python. 

Некоторые IT-специалисты полагают, что ООП теряет свои позиции, поэтому нет смысла тратить время на освоение его основных принципов. Им представляется нелогичным использовать объекты вместо нисходящей методики традиционного программирования в таких языках, как Visual Basic.

Если вы писали код для подобного ПО, то, возможно, привыкли разбивать сложные задачи на более простые и решать их в отдельных сегментах кода. Уловив суть ФП, которое рассматривает элементы кода как правильные математические функции и запрещает им менять другие аспекты, вы понимаете, что вывод отражает ввод пользователя. 

Несмотря на растущую известность ФП, ООП всё еще в деле. Ниже рассмотрим причины, по которым ФП не вытеснило ООП. 

Повторное использование кода через наследование 

Допустим, у вас есть объект Table, другому дополнительно понадобился объект Metallic Table, а чему-то необходим объект Glass Table. Вы создаете их по отдельности, при этом замечаете между ними сходство. Каждый из объектов является просто разновидностью Table. Именно в этой ситуации метод наследования помогает сэкономить время. Для этого вам потребуется создать один базовый класс Table, после чего определить подклассы Metallic и Glass для заимствования его свойств. 

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

Предположим, вы намерены внести изменения во все объекты Table, независимо от типа. В этом случае вам потребуется всего лишь скорректировать класс Table, и тогда все объекты Table присвоят новый код. По этой причине некоторые разработчики по-прежнему отдают предпочтение ООП. 

Полиморфизм и гибкие возможности 

Вышеприведенный пример показывает, что вам не нужно много функций, чтобы начать. Например, объекты Metallic Table и Glass Table имеют общие черты, но при этом каждый из них обладает собственными уникальными свойствами. 

Здесь в игру вступает полиморфизм, поскольку одна функция может наследовать свойства родительского класса. Например, родительский класс Table, именуемый maintenance, будет работать с MetallicTableMaintenance и GlassTableMaintenance. Этот пример демонстрирует важнейшую роль полиморфизма в разработке ПО.  

Эффективное решение задач 

Такой язык, как С, пользуется достойной репутацией в мире программирования, но не стоит браться за разработку ПО на языке программирования низкого уровня, если только вы им не владеете на 5+. Иначе можно просто провалиться с проектом. А вот написать программу на высокоуровневом языке ФП, например Haskell или ML,  —  гораздо проще.

Как только вы начинаете использовать ООП, оно, как правило, становится для вас наиболее естественным и разумным подходом. Его языки позволяют разработчикам разбивать ПО на небольшие задачи, которые можно решить по отдельности.  

Абстракция данных 

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

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

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

В языках ООП абстракция реализуется через интерфейсы и абстрактные классы. Используя интерфейсы, можно достичь 100% абстракции. 

Заключение 

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

Читайте также:

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи StefanBStreet: Is Functional Programming the Future’s Best Coding Paradigm

Предыдущая статьяАспектно-ориентированное программирование в JavaScript
Следующая статья10 полезных инструментов для разработчика