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

Недавно я добавил в свой список новый инструмент — Функциональное программирование, о нем и пойдет речь в этой статье.

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

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

Почему Javascript?

У нас были доступные функциональные языки программирования, такие как Scala, тогда почему я выбрал Javascript?

Причина для меня была проста: я использую React в своих повседневных задачах, и я могу напрямую перенести свои знания о концепциях Javascript в функциональное программирование и немедленно начать использовать концепции функционального программирования для улучшения моего кода React. Что, кстати, очень близко следует за функциональным программированием.

Дополнительным преимуществом Javascript является потрясающая встроенная поддержка функционального программирования.

Выбор библиотеки функционального программирования в JS

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

Ramda упростила FP для разработчиков JavaScript — в то время это никому не удавалось.

Он заимствует фундаментальные идеи FP, в том числе

  1. Акцент на чистых функциях
  2. Все приправлено карри
  3. Pipe/Compose включены и поощряются
  4. Функции берут свои данные последними

Теперь давайте углубимся в основные концепции функционального программирования, посмотрим немного кода :)

Основные понятия функционального программирования

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

Строительные блоки функционального программирования — это чистые функции, то есть функции, обладающие следующими двумя свойствами:

а. Тот же ввод => Тот же вывод

б. Никаких побочных эффектов (console.log, изменение глобальной переменной, зависимость, запрос DOM, вызовы AJAX)

// Pure function.
function add2Numbers(a, b) {
    return a + b;
}
// Impure function.
function add2NumbersImpure(a, b) {
    console.log("Hello");
    return a + b;
}

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

2. Функциональная композиция

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

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

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

Хватит разговоров, давайте посмотрим код композиции функций.

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

// Array.map --  A higher order function that will take a callback
// and maps the each elemnt of array into new element based on 
// return from the callback.
const numbers = [1, 2, 3, 4, 5];
const squares = numbers.map(num => num * num)
// let's get sum of the squares.
const sum = squares.reduce((acc, val) => acc + val, 0);
// Now let's say the question is to find sum of the square 
// in one step from numbers array, we can combine these stpes 
// like below
const sumInOneStep = numbers
                        .map(num => num * num)
                        .reduce((acc, val) => acc + val, 0);
// Now let's see how Ramda's composition helps us here to tell 
// the same idea but in more convenient way
import { pipe } from 'ramda';
const adder = pipe(squares, sum);
const sumRamdsPiped = adder(numbers)
// neat, right?

3. Неизменность

Так что это просто, если вам нужно изменить данные, просто создайте новую копию. Нет обмена данными (состоянием). Один из основных принципов FP заключается в том, что данные неизменны. поэтому, если вы хотите использовать array.push в JS FP, вы изменяете массив, замените этот код, возвращая новый массив, например […array, newElement].

Это все, ребята, для введения в функциональное программирование, следите за обновлениями для следующей статьи, где я углублюсь в RamdaJS и функциональное программирование.