Понимание основ функционального программирования было для меня постоянной задачей в течение многих лет. Я ходил туда и обратно. Впервые я каким-то образом почувствовал, что это щелкнуло, когда я прочитал «Mostly Adequate Guide to Functional Programming» Брайана Лонсдорфа. Эта книга позволила мне изучить основы функциональной парадигмы без изучения нового (функционального) языка программирования. Брайан продемонстрировал, что мы можем сделать это и на самом популярном сегодня языке — JavaScript.

Для меня глава 5 была самойглавой. Речь идет о компонуемости и бесточечном стиле.

Использовать бесточечный стиль в программном коде означает создавать функции без явного указания данных. Ух ты!

Но ждать! Зачем мне создавать функции без явного указания моих данных? Есть несколько плюсов (и минусов).

Давайте создадим функцию для записи на стандартный вывод:

const log = data => console.log(data)

Ждать! Разве console.log не принимает несколько параметров (уже проблема с именем параметра)? Итак, мы должны расширить определение нашей функции, в зависимости от типа data, который представляет что-то слишком общее (еще одна проблема с именем параметра).

Следовательно, нам придется пойти по этому пути:

const log = data => {
  Array.isArray(data)
    ? console.log(...data)
    : console.log(data)
}

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

Pointfree спешит на помощь!

const log = console.log

Ух ты! Любить это! Сделанный.
(Обратите внимание, что нам, вероятно, следует привязать функцию журнала к консоли, поскольку может быть какой-то движок, который требует этого:
const log = console.log.bind(console)).

Некоторые преимущества этого стиля:

  1. Меньше кода для написания
  2. Меньше вещей, которые нужно называть (вспомните одну из двух сложных вещей в информатике)
  3. Более масштабируемый API (если среда выполнения изменяет свой console.log API, нам не нужно менять определение нашей log функции, за исключением критических изменений).

Этот стиль обычно используется с функциональной композицией. Пожалуйста, сравните две функции; первый - обычный, а второй - бесточечный:

const shout = text => exclaim(toUpperCase(text))
const shout = compose(exclaim,toUpperCase)

Ух ты! Это выглядит чистым. Мы избавились от такого универсального имени переменной, которое служило заполнителем буквально для всего, что имеет строковый тип.

Механика композиции

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

Быть или не быть

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

И я считаю, что я пропустил один. Итак, вау!