Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Парадигмы программирования JS: Функции

В программировании часто используется термин "парадигма".

Паради́гма программи́рования — это совокупность идей и понятий, определяющих стиль написания компьютерных программ (подход к программированию). Это способ концептуализации, определяющий организацию вычислений и структурирование работы, выполняемой компьютером. (Wikipedia)

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

Paradigms

Императивная парадигма

Императивная парадигма — стиль написания кода в виде набора последовательных инструкций (команд) с активным использованием переменных. Возможно, данное определение звучит страшно, но на практике императивный стиль является доминирующим. Не считая этого курса, весь остальной код мы писали именно в императивном стиле.

// Поиск максимального числа
const numbers = [10, 20, 52, 105, 56, 89, 96];

let max = numbers[0];
for (const number of numbers) {
  if (number > max) {
    max = number;
  }
}

console.log(max); // => 105

В императивном стиле широко используется присваивание (а значит, и переменные) и циклы. Эта парадигма популярна потому, что она в точности соответствует тому, как работает компьютер: последовательно выполняет инструкции и использует память для хранения промежуточных результатов. Обычно говорят, что императивная программа отвечает на вопрос КАК («как достичь нужного результата»).

JavaScript, впрочем, как и Java/Ruby/Python/C#/Perl/PHP/Go, относится к императивным языкам. То есть языкам, в которых доминирующей является императивная парадигма (язык толкает к её использованию). Что, однако, не мешает использовать и другие парадигмы в рамках этих языков.

Декларативная парадигма

Императивному стилю противопоставляют декларативный, который нередко называют функциональным. Ключевое отличие функционального стиля от императивного в том, что при таком стиле программа выглядит как спецификация (которая может быть очень сложной), а не как набор инструкций. То есть программа отвечает на вопрос ЧТО («что мы хотим получить»). Эту грань довольно трудно уловить сразу, но, например, вся математика, по своей сути, декларативна.

// Поиск максимального числа
const numbers = [10, 20, 52, 105, 56, 89, 96];

const max = numbers.reduce(
  (acc, number) => number > acc ? number : acc,
  numbers[0],
);

console.log(max); // => 105

Главное отличие декларативной парадигмы от императивной на практике — отсутствие присваивания. Вы можете мне возразить, что в коде выше определяются константы и в них сохраняются значения. Присмотритесь к коду внимательнее, вы заметите что константы создаются ровно один раз, инициализируются первоначальными значениями, которые больше не меняются (в этом смысл констант). Конструкцию, типа const myVar = expression, можно рассматривать как логическое высказывание. В математике это звучало бы так: "допустим, A — это множество чисел". Что бы мы дальше ни делали, "A" остаётся всегда тем же, чем было во время определения.

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

То же самое касается и acc с number. Эти параметры всегда определяются ровно один раз, так как каждый вызов функции при таком определении (без использования ссылок) не зависит от другого вызова. В мире функциональных языков такую операцию называют связывание. Визуально оно выглядит как присваивание, но это не оно. Попытка связать уже связанный идентификатор (в функциональных языках нет переменных) завершится ошибкой. Ниже пример на языке Erlang:

1> A = 4.
4
2> A = 'hey'.
** exception error: no match of right hand side value hey

Отсутствие присваивания автоматически означает то, что в функциональной парадигме невозможно использование циклов. Вместо них используется рекурсия. Другой важной особенностью функционального стиля считается активное использование функций как объектов первого рода. В основном в функциях высшего порядка. Причём они способны заменить рекурсию в подавляющем большинстве задач, в чем мы уже убедились в предыдущих уроках (убедились так, что даже не рассматривали рекурсию). Любая задача из представленных решалась основной тройкой функций высшего порядка.

Языков, использующих декларативную парадигму, довольно много. Они, в своей массе, менее популярны, чем императивные, но прочно занимают определённые ниши и активно используются в промышленном программировании. К таким языкам относятся: Haskell/Erlang/Elixir/OCaml/F#. В этих языках нет присваивания и циклов. Императивный код на них написать просто невозможно. Немного особняком стоят такие языки, как Scala и Clojure (и другие из семейства LISP). В этих языках основная парадигма — декларативная, и язык толкает к тому, чтобы писать в таком стиле, но при необходимости на них можно написать самый настоящий императивный код с присваиванием и циклами. А вот почти все императивные языки позволяют писать декларативно. Причём, если одни языки имеют довольно слабую поддержку декларативной парадигмы, то другие настолько мощную, что в них можно писать только декларативно (если хочется). К последним относится и современный JavaScript.

Другие парадигмы

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

  • Логическое программирование
  • Автоматное программирование
  • Объектно-ориентированное программирование
  • Метапрограммирование

Дополнительные материалы

  1. Парадигмы
  2. Ссылочная (референциальная) прозрачность

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

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

  • 120 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

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

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
8 декабря 8 месяцев
Иконка программы Node.js-разработчик
Профессия
Разработка бэкенд-компонентов веб-приложений
8 декабря 8 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»