Нет, это не связано с ИИ

Программирование - это, по большей части, умеренно веселое и полезное занятие. Но вы когда-нибудь смотрели на фрагмент кода и думали: «Боже, мне это нравится, но я действительно хочу, чтобы это было забито целой кучей математики»? О, никогда. Ну, кучка ботаников в сообществе компьютерных наук, то есть супер-ботаники, собрались в 50-х, чтобы сделать именно это. Так родилось функциональное программирование, новое модное слово сегодня.

Начала

Вначале был ручной расчет. Затем Тьюринг сказал: пусть будет механизация, и так родилась машина Тьюринга. Затем пришел Алонзо Черч, который сказал, что пусть будет формальная система вычислений, построенная на основе функционального приложения, что привело к созданию лямбда-исчисления. Так и родилась функциональная парадигма.
Хотя внутренняя работа самого лямбда-исчисления не важна для нашего разговора, стоит знать основы, поскольку они составляют основу всей этой парадигмы программирования. . Итак, на базовом уровне это математическая модель вычислений, которая включает привязку значений к параметрам функции и применение указанных функций.

Мотивация

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

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

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

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

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

Функции высшего порядка

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

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

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

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

Чистые функции

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

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

Рекурсия

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

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

Ленивая оценка

Это концепция, при которой значение не оценивается до тех пор, пока в этом нет необходимости. Например здесь

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

Другой пример, который сравнительно немного интереснее, можно показать с помощью бесконечных списков.

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

Заключение

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