Перейти к содержанию
Innovialabs

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

Основы4 мин

Коротко

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

Короткий ответ

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

Специальный язык не нужен. JavaScript, Python, Kotlin, C# и многие другие поддерживают основные идеи ФП, а большая часть современного кода смешивает ФП с другими стилями.

Идея 1: функции — это значения

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

const greet = (name) => `Hello, ${name}`;
const actions = { greet };
console.log(actions.greet("Aziza"));
def greet(name):
    return f"Hello, {name}"

say = greet
print(say("Aziza"))

Идея 2: функции высшего порядка

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

const multiplier = (factor) => (x) => x * factor;
const double = multiplier(2);
double(5); // 10

Возвращённая функция помнит factor — это называется замыкание.

Идея 3: map, filter, reduce

Эти три функции высшего порядка закрывают большую часть повседневной работы со списками:

ФункцияЧто делаетРезультат
mapпреобразует каждый элементсписок той же длины
filterоставляет элементы, прошедшие проверкусписок короче или той же длины
reduceсворачивает все элементы в одно значениеодно значение

Императивная версия

const orders = [
  { total: 120, paid: true },
  { total: 80, paid: false },
  { total: 50, paid: true },
];

let sum = 0;
for (let i = 0; i < orders.length; i++) {
  if (orders[i].paid) {
    sum += orders[i].total;
  }
}

Функциональная версия

const sum = orders
  .filter((o) => o.paid)
  .map((o) => o.total)
  .reduce((acc, t) => acc + t, 0);

То же на Python, где идиоматичнее использовать генераторные выражения:

orders = [
    {"total": 120, "paid": True},
    {"total": 80, "paid": False},
    {"total": 50, "paid": True},
]

total = sum(o["total"] for o in orders if o["paid"])

В Python тоже есть map, filter и functools.reduce, но генераторные выражения и встроенные функции вроде sum обычно читаются лучше.

Императивный и декларативный стиль

  • Императивный код описывает как: завести счётчик, пройти циклом, проверить, обновить.
  • Декларативный код описывает что: оплаченные заказы, их суммы, итог.

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

Другие ключевые идеи

  • Чистые функции: одинаковый вход всегда даёт одинаковый выход, без побочных эффектов. Их легко тестировать и понимать.
  • Иммутабельность: вместо изменения данных создаётся новая версия. Это защищает от ошибок, когда одна часть кода незаметно меняет данные, на которые полагается другая.
  • Композиция функций: большие функции собираются из цепочки маленьких, где выход одной — вход следующей.

Как начать применять ФП в обычном коде

  1. Заменяйте простые циклы for, которые собирают новые списки, на map / filter или генераторы списков.
  2. Выносите вычисления в маленькие функции, которые используют только свои аргументы.
  3. Возвращайте новые объекты вместо изменения аргументов.
  4. Держите побочные эффекты (база данных, сеть, логи) на краях программы.
  5. Не перегибайте: если цепочка стала трудно читаться, разбейте её на именованные шаги.

Частые ошибки

  • Использовать map просто как цикл ради побочных эффектов — для этого есть forEach или обычный цикл.
  • Строить очень длинные цепочки, которые никто не может отладить.
  • Забывать начальное значение в reduce — в JavaScript это ломается на пустом массиве.
  • Считать, что ФП — это «всё или ничего». Смешивать стили нормально.

Частые вопросы

Нет. Основные идеи можно освоить на JavaScript или Python, которые вы, возможно, уже используете. Чисто функциональные языки пригодятся позже, если захотите копнуть глубже.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

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

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.