СоХабр закрыт.

С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.

| сохранено

H Javascript и функциональное программирование: Введение в черновиках Перевод

image


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

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

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

У меня было ощущение, что должен существовать лучший, более чистый подход к разработке программного обеспечения. Я слышал разговоры о функциональном программировании и как оно позволяет разработчикам писать более сжатый и элегантный код. Впервые я столкнулся с функциональными парадигмами и паттернами при работе с React и Redux. Они оба включали в себя некоторые из принципов, и мне они понравились. Я прочитал о ФП и сначала мне показалось, что его парадигмы основаны на абстрактных математических концепциях и что оно очень распространено в академических кругах. Так как моя цель — как можно быстрее создать проект, это показалось мне неконкурентным подходом к тому, чего я пытался достичь. Спустя 4 года в инженерной школе я был уверен, что теоретики от ФП занимаются только теоретическими проблемами и вряд ли когда-нибудь помогут мне в повседневной работе над созданием приложений.

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

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

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

Императивный подход



// triple the value of every element in a given array
const triple = (arr) => {
  let results = []
  for (let i = 0; i < arr.length; i++){
    results.push(arr[i] * 3)
  }
  return results
}

// sum all the elements in a given array
const sum = (arr) => {
  let result = 0
  for (let i = 0; i < arr.length; i++){
    result += arr[i]
  }
  return result
}


Вам этот код кажется плохим? А должен! Каковы сходства между вышеприведенными методами?

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


Декларативный подход


Давайте перепишем этот фрагмент кода, но декларативным стилем.

// triple the value of every item in a given array
const triple = (arr) => arr.map((currentItem) => currentItem * 3)

// sum all the elements in a given array
const sum = (arr) => arr.reduce((prev, current) => prev + current, 0)


.map? .reduce? Что за черная магия?

Я гарантирую, что при тех же входных параметрах, результат будет тот же.

Небольшое отступление по декларативному фрагменту

.map () — метод, доступный из каждого массива в JS. Метод .map () создает новый массив с результатами применения функции к каждому элементу в массиве.

.reduce () — это метод, который применяет функцию-свертку к аккумулятору и каждому элементу массива (слева направо), чтобы свернуть его до одного значения.

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

Декларативный подход будет полезен нам во всех начинаниях:

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


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



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

комментарии (2)

0
tmnhy ,  
Вот, судя по таким статьям, если в коде встречается map и filter, и иногда reduce, то код автоматически становится функциональным. Но это не так.

Позволяет писать более короткий, выразительный и сжатый код.

Тоже спорно, можно функцию, применяемую к массиву сделать такой, что код будет читаться не лучше чем и при обычном for.
0
VolCh ,  

Надо было сразу продолжение публиковать, а то ввредение само по себе ценности почти не несёт.