Императивное программирование — это парадигма программирования (стиль написания исходного кода компьютерной программы), в которой задается последовательность действий, необходимых для получения результата. В нем используются переменные, операторы присваивания и составные выражения. Это такой стиль программирования, при котором вы описываете, как добиться желаемого результата. Примерами императивных языков являются Java, Python, JavaScript, C, C++.
Декларативное программирование — это парадигма программирования, в которой задается спецификация решения задачи: описывается, что представляет собой проблема и ожидаемый результат, но без описания способа достижения этого результата. В декларативных языках обычно отсутствует изменение переменных или обычно спрятано за каким-либо специальным механизмом. К подвидам декларативного программирования часто относят и функциональное программирование. Пример декларативного языка: SQL.
Несмотря на то, что исторически первым был применен декларативный подход в программировании, первые языки программирования компьютеров (машинный, ассемблер) были императивными в силу простоты подхода. Для императивного программирования характерно следующее:
- в исходном коде программы записываются иструкции (команды);
- инструкции должны выполняться последовательно;
- данные, получаемые при выполнении предыдущих инструкций, могут читаться из памяти последующими инструкциями;
- данные, полученные при выполнении инструкции, могут записываться в память.
Декларативное программирование распространено не так обширно, как императивное, хотя оказывает большое влияние. Смысл декларативного программирования в том, что программы пишут в виде некоторых ограничений и правил. Логические языки, такие, как Пролог, предлагают описывать ограничения в виде фактов и правил.
В функциональных языках описывают программу в виде функций. Отличие от функций в императивном программировании заключается в том, что функции в функциональном языке являются математическими в том смысле, что они устанавливают отношение между аргументом и результатом, и не могут изменять никаких переменных во время вычислений.
Выбор того или иного стиля программирования — императивного или функционального — определяется, главным образом, требованиями к программе и набором достоинств и недостатков каждой из стилей. Так, например, независимость функций по данным в функциональных языках и отсутствие побочных эффектов чрезвычайно сокращает количество ошибок и позволяет эффективно распараллеливать код. Поэтому для создания высоконагруженных систем с высоким уровнем параллельных вычислений более оправданно выбирать один из функциональных языков.
С другой стороны, неизменность входных данных в функциональных языках программирования затрудняет создание систем, активно выполняющих ввод-вывод и модификацию уже имеющихся данных. Для реализации таких систем предпочтительнее выбирать императивные языки.
На практике, при написании кода и выбора подхода, разработчик отталкивается не только от возможностей и ограничений языка программирования, но и удобства использования той или иной парадигмы в данном конкретном случае.
Самым сложным является тот факт, что разница между декларативным и императивным подходами часто понятна интуитивно, но ее сложно задать определением. Лучшее объяснение — это сочетание метафор и примеров кода.
Императивный подход (как): Я вижу, что тот угловой столик свободен. Мы пойдем туда и сядем там.
Декларативный подход (что): Столик для двоих, пожалуйста.
Императивный подход означает то, как вы займете место. Вы должны перечислить все шаги этого процесса. Декларативный же подход заявляет, что нужен столик на двоих.
Примеры кода: дан массив чисел, надо написать функцию, которая вернет массив чисел, где каждое число из исходного массива удваивается. Т.е. [1, 2, 3] -> [2, 3, 6]
Императивный стиль:
function double (arr) {
let results = [];
for (let i = 0; i < arr.length; i++){
results.push(arr[i] * 2);
}
return results;
}
Декларативный стиль:
function double (arr) {
return arr.map((item) => item * 2);
}