Как начать думать функционально в JavaScript
Перевод статьи How to Start Thinking Functionally in JavaScript с сайта itnext.io для css-live.ru, автор — Алекс Рицкован.
Фото Denys Nevozhai с Unsplash
Функциональное программирование – это стиль программирования, который требует от специалиста думать на более высоком уровне абстракции. Как правило, когда мы учимся программировать, мы рассматриваем задачи в весьма императивном и процедурном стиле: сначала делаем это, потом – то и т.д.
Мы настолько озабочены синтаксисом и правилами языка, что даже не думаем о том, чтобы мыслить более абстрактно.
Это плохо, потому что потом, когда мы больше не будем поглощены правилами и синтаксисом, нам придется переучивать свой мозг думать по-другому.
Чтобы освоить навык функционального программирования – или ФП, как его иногда называют по-модному – потребуется время; но как только вы вникнете в суть, вам откроется целый новый мир. Вы также сможете разрабатывать код, который легче поддается анализу.
С помощью ФП вы сможете перейти от императивного стиля кодирования к более декларативному.
Обычно разницу между ними объясняют так: декларативное программирование направлено на то, что именно программа должна выполнить, а императивное – на то, как она должна этого достичь.
Если не совсем понятно, ничего страшного. Просто давайте сядем и разберемся с этим вместе.
Рассмотрим простой пример в JavaScript.
Императивный способ
Допустим, у нас есть массив домашних животных.
Каждый элемент массива – это объект, определяющий питомца.
Предположим, что в бизнес-требованиях предусмотрена фильтрация объектов по следующим критериям: питомец старше 7 лет черного окраса.
Для каждой совпадающей записи нам нужно создать строку в следующем формате:
<petName>
, возраст: <age>
лет, цвет: <color>
.
Теперь, когда мы знаем, каким должен быть результат, как мы его получим?
Сначала рассмотрим императивный способ решения задачи. Код будет таким.
всё очень императивно!
В строке 1 мы создаем новый массив для сбора результатов, удовлетворяющих бизнес-требованиям. Затем в строке 2 создаем цикл for. В каждой итерации цикла получаем название питомца в строке 3 и проверяем его свойства в строке 4, чтобы увидеть, подпадает ли он под наши критерии.
Если условие выполняется, вставляем новую строку в массив outputArr
.
Наконец, в строке 8 мы вызываем метод console.table()
, который выводит новый массив в консоль.
Мы получили такие выходные данные.
отфильтрованные записи в консоли
Обратившись к исходным данным, мы увидим, что наш код работает правильно. Есть только 2 записи, которые соответствуют критериям фильтрации.
В этом коде нет ничего плохого. Он работает, но при этом нам приходится погружаться в детали и продумывать каждое действие. Мы явно задаем каждый шаг, чтобы получить то, что хотим.
Есть ли лучший способ? Думаю, да. Давайте его рассмотрим.
Декларативный способ
Давайте отвлечемся и подумаем о том, что мы хотим сделать, с более глобальной точки зрения. К чему мы придем? Скажу простыми словами:
“Я хочу отфильтровать массив по ряду критериев и вывести строку данных.”
Я намеренно не думаю о реализации. Мои мысли парят не в трех метрах, а в трех километрах над задачей.
Слова, которые первыми приходят на ум – отфильтровать и вывести строку. Это можно записать так:
pets.filter().map()
а вот фактическая реализация
декларативная версия № 1
Выглядит лучше, правда? Почти как предложение на английском. Именно это люди имеют в виду, когда говорят, что ФП носит декларативный характер: мы объявляем, чего хотим достичь. Конечно, нам в любом случае приходится прописывать логику фильтра, но само решение выглядит более элегантным и его легче анализировать. Нам не нужно изучать каждую строку цикла for, чтобы понять, что происходит.
Но я бы пошел ещё дальше. Следуя правилу DOT (Do One Thing, одна функция – одно действие), я бы сделал такой рефакторинг кода.
декларативная версия № 2
Я разбил логику фильтра на две отдельные функции (помните: одна функция – одно действие) и добавил логику создания строки.
Теперь, чтобы получить необходимые выходные данные, нужно просто последовательно соединить функции .filter()
и .map()
и передать новые функции в качестве аргументов (строка 5). Выходные данные в консоли точно такие же.
код чище – выход тот же
Выводы
1. Функциональное программирование – это стиль программирования, в котором задачи рассматриваются на более высоком уровне абстракции.
2. Большинство из нас учится программировать на процедурном и императивном уровне, поэтому для начинающих переход к ФП может быть трудным.
3. Код, написанный в функциональном стиле, в целом легче читать и анализировать.
4. Функциональный код проще поддерживать и модифицировать.
Ресурсы
Чтобы продолжить знакомство с ФП, ознакомьтесь с книгой “Eloquent JavaScript” (бесплатно).
И как всегда, спасибо, что прочитали статью! Если она вам понравилась, посмотрите другие мои записи здесь на Medium.
P.S. Это тоже может быть интересно:
Автор забыл написать, про
1) крайне токсичное сообщество, пришедшее кто со scala а кто из haskel, общающееся в основном на своём птичьем языке, и нетерпимое к новичкам.
2) написанные в таком стиле программы через неделю сможет прочесть только тот кто написал, да и то с трудом).
И я не про примеры из статьи, а про обилие импортов и функций используемых в основном один-два раза. И про особые вещи о которых не говорят в вводных статьях вроде этой. Как например some(many(wrapoed, and, not(readable)), constructions), с каррированиями, атомами и обзёрвеблами на ровном месте.
Я считаю, что не надо слишком увлекаться, потому что пишем мы единожды а читать придётся не менее десятка раз.
Более вдохновляющей показалась эта статья: https://lucasmreis.github.io/blog/pointfree-javascript/
Я сначала опешил от того что автор заявил будто три итерации лучше одной, а потом вспомнил что я читаю css-live
не важно три их или 5 или одна.
важно чтобы они не были вложенными.
Всё дело в сложности алгоритмов (гугли big O)
Я не спорю что это ФП, но как по мне пример с превращением for в filter, map ну настолько заезженный и банальный что дальше некуда.
Здравствуй, соискатель!
Ты давно на просторах интернета, но так и не нашёл хорошего сообщества по фронденту? Не беда, сейчас исправим.
В нашем сообществе всё понятно и доступно. Что именно в нём есть?
1) Полезные статьи, что помогут тебе в развитии;
2) Разнообразные розыгрыши (последние были носки и почему то все хотели их);
3) Сложные задачи и пути их решения;
4) Опросы, чтобы узнать более актуальную информацию;
5) Также можно получать достижения;
Заходи к нам ТЛГ deveveloper_house_jun_front
Здравствуй, соискатель!
Ты давно на просторах интернета, но так и не нашёл хорошего сообщества по фронденту? Не беда, сейчас исправим.
В нашем сообществе всё понятно и доступно. Что именно в нём есть?
1) Полезные статьи, что помогут тебе в развитии;
2) Разнообразные розыгрыши (последние были носки и почему то все хотели их);
3) Сложные задачи и пути их решения;
4) Опросы, чтобы узнать более актуальную информацию;
5) Также можно получать достижения;
Заходи к нам ТЛГ deveveloper_house_jun_front