Вряд ли вы не слышали о таких понятиях, как декларативное и императивное программирование. В этой статье мы рассмотрим императивный и декларативный подход, а также основные языки программирования (programming language), которые эти подходы используют. Давайте начнем.

Если посмотреть определение в англоязычной Википедии, мы увидим приблизительно следующее:

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

С первого взгляда ничего не понятно, а словосочетания типа «парадигма программирования» и вовсе звучат слишком претенциозно. Такие фразы любят говорить профессоры в университетах, но это не добавляет понимания, если за ними не следуют конкретные примеры.

Давайте попробуем объяснить более простыми словами:

  1. Императивный подход описывает, каким образом ты что-то делаешь.
  2. Декларативный описывает, что именно ты делаешь.
Императивное и декларативное программирование

То есть в первом случае у нас стоит вопрос «Как?», а во втором — «Что?» И все равно разница ясна лишь интуитивно, поэтому без практических примеров не обойтись. Но начать лучше стоит с метафор.

Давайте представим, что вы попросили вашего товарища нарисовать пейзаж, а как он это сделает, для вас значения не имеет — это декларативный путь, когда дается ответ на вопрос «Что именно надо сделать?»

В императивном случае ситуация следующая:

— вы попросили товарища нарисовать пейзаж;

— он попросил, к примеру, Никаса Сафронова, рассказать ему, как рисуются пейзажи;

— Никас Сафронов как мастер своего дела предоставил пошаговые инструкции — как именно нарисовать этот пейзаж.

Императивное и декларативное программирование

Императивные и декларативные языки программирования

Примеры декларативных языков программирования:

  • SQL;
  • HTML.

Императивные языки:

  • C,
  • C++,
  • Java.

Также выделяют смешанные языки:

  • JavaScript,
  • C#,
  • Python.

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

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

Декларативный язык SQL:

Императивное и декларативное программирование

Язык HTML:

Императивное и декларативное программирование

Нам достаточно просто взглянуть на код, чтобы понять суть происходящего. Языки программи рования в данном случае заявляют, не как что-то надо сделать, а что именно должно быть сделано, поэтому можно говорит о декларативности. То есть мы описываем  желаемый результат и не углубляемся в инструкции. И для нас абсолютно не имеет значения, как будет сделана выборка пользователей из Мексики и как web-браузер распарсит article. Главное, что мы получим этих самых пользователей, а также новый header и paragraph на веб-сайте.

И снова код

Для следующего примера воспользуемся языком программирования JavaScript. Давайте представим, что мы находимся на собеседовании. Нам поставлены следующие задачи:

— написать функцию с названием double, принимающую массив чисел и возвращающую новый массив, причем каждый элемент нового массива больше исходного в 2 раза:

Императивное и декларативное программирование

— написать функцию с названием add, принимающую массив и возвращающую сумму всех элементов массива:

Императивное и декларативное программирование

— используя библиотеку jQuery (либо чистый язык JavaScript), выполните добавление обработчика событий click к элементу с идентификатором (id), равным btn. При нажатии выполните переключение класса highlight и замените текст на Add Highlight либо Remove Highlight с учетом того, каково текущее состояние элемента.

Задания, есть, давайте попробуем их решить. Начнем с императивной парадигмы и воспользуемся наиболее распространенными подходами.

Императивное и декларативное программирование

Теперь поговорим, что общего у этих примеров, и почему они являются именно императивными, а не декларативными:

  1. Во всех случаях описывается, как именно решить проблему, то есть явно указываются все шаги по решению поставленной задачи.
  2. Следующий момент не так очевиден для тех, кто имеет привычку думать декларативно либо даже функционально. В каждом из вышеописанных примеров осуществляется изменение какого-нибудь состояния. И если в первых 2-х случаях происходит изменение переменной results, то в 3-м случае состояние находится в самой DOM, причем его мы тоже меняем.
  3. Если говорить субъективно, то код можно считать, по сути, нечитаемым. А все потому, что с первого раза вы вряд ли поймете, что конкретно происходит, — вместо этого вам придется внимательно читать программный код построчно.

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

Императивное и декларативное программирование

Теперь стало гораздо лучше, не находите?

Обратите внимание, что в первых 2-х примерах применяются встроенные в язык JavaScript методы: map и reduce. То есть в нашем случае декларати вное программирование — это абстракции над императивными реализациями, но на деле нас мало волнует, как эти методы реализованы. Мы тоже не меняем состояния, да и сам программный код стал более читаемым.

В 3-м примере при написании кода мы пошли на хитрость, так как задействовали библиотеку языка JavaScript под названием React. Но важно не это, а то, что все 3 императивные ошибки нами исправлены. Да и само программи рование на React хорошо еще и тем, что предоставляет возможность создавать декларативные пользовательские интерфейсы. Если посмотреть на тот же компонент Btn, сразу становится понятно, как конкретно станет выглядеть интерфейс. А еще состояния «живут» не в DOM, а непосредственно в React-компоненте.

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

По материалам статей:

  • «Imperative vs Declarative Programming» — https://ui.dev/imperative-vs-declarative-programming/;
  • «Declarative vs Imperative Programming» — https://codeburst.io/declarative-vs-imperative-programming-a8a7c93d9ad2.