Императивное программирование — это стиль, при котором программу описывают как последовательность команд, шаг за шагом меняющих состояние, то есть отвечают на вопрос «как получить результат». Декларативное программирование — это стиль, где описывают желаемый результат («что получить»), а способ его достижения берет на себя исполнитель: компилятор, движок базы данных, браузер, библиотека.
Содержание
Ниже разберем разницу на одном и том же примере в двух стилях с фактическим выводом, покажем декларативность SQL, HTML и React, разложим парадигмы внутри каждого подхода (процедурное, ООП, функциональное) и дадим таблицу сравнения с признаком выбора.
Как vs что: разводим два вопроса
Проще всего запомнить пару так: императивный код говорит машине «как», декларативный — «что».
- Императивный: «заведи счетчик, пройди список, на четных прибавь квадрат к счетчику, верни счетчик».
- Декларативный: «дай сумму квадратов четных чисел».
Во втором случае мы не пишем цикл и не заводим переменную-накопитель — за нас это делает встроенная функция или движок. Это не значит, что цикла «нет»: он есть, но спрятан в реализацию, и нам не важно, как именно он устроен.
Важно не путать три близких термина. Парадигма — крупное семейство подходов (императивная, декларативная). Стиль — как вы пишете конкретный код, его можно менять внутри одного языка. Язык — инструмент, который чаще всего поддерживает несколько стилей сразу.
Один пример в двух стилях
Возьмем задачу: посчитать сумму квадратов четных чисел списка. Сначала императивно, на Python — явно каждый шаг.
nums = [1, 2, 3, 4, 5, 6]
total = 0 # заводим состояние
for n in nums: # сами управляем обходом
if n % 2 == 0: # условие вручную
total += n * n # меняем состояние на каждом шаге
print(total) # 56
Четные — это 2, 4, 6; их квадраты 4, 16, 36; сумма 56. Мы описали весь механизм: переменную, цикл, условие, накопление.
Теперь декларативно — то же самое, тем же языком, но описываем результат:
nums = [1, 2, 3, 4, 5, 6]
total = sum(n * n for n in nums if n % 2 == 0)
print(total) # 56
Вывод тот же — 56. Мы не заводили total вручную и не меняли его в цикле; мы сказали «сумма квадратов четных», а перебор sum выполнил сам. Тот же результат дает вариант через map/filter:
nums = [1, 2, 3, 4, 5, 6]
total = sum(map(lambda n: n * n, filter(lambda n: n % 2 == 0, nums)))
print(total) # 56
Оба декларативных варианта короче и не заводят изменяемое состояние — меньше мест, где можно ошибиться. Императивный вариант при этом нагляднее показывает механику и дает полный контроль над каждым шагом. Это и есть граница выбора, а не «один всегда лучше».
Декларативность SQL, HTML и React
SQL — декларативный язык запросов. Вы описываете, какие данные нужны, но не как их искать:
SELECT city, COUNT(*) AS users
FROM users
WHERE country = 'Mexico'
GROUP BY city;
Мы не пишем, как перебрать таблицу, использовать ли индекс и в каком порядке соединять данные — это решает оптимизатор СУБД. Императивный эквивалент «вручную» — тот самый цикл со счетчиком и условием, как в примере выше, только по строкам таблицы.
HTML — декларативный язык разметки (это разметка, а не язык программирования в полном смысле: без переменных и логики). Вы объявляете структуру, а как ее нарисовать и разложить по экрану, решает браузер:
<article>
<h1>Заголовок</h1>
<p>Абзац текста.</p>
</article>
React переносит декларативность на интерфейс. Сравним. Императивно на чистом JavaScript мы шаг за шагом меняем DOM — состояние живет в самой странице:
const btn = document.getElementById('btn');
btn.addEventListener('click', () => {
if (btn.classList.contains('highlight')) {
btn.classList.remove('highlight');
btn.textContent = 'Add Highlight';
} else {
btn.classList.add('highlight');
btn.textContent = 'Remove Highlight';
}
});
Декларативно в React мы описываем, как интерфейс должен выглядеть при данном состоянии, а обновлением DOM занимается сам React:
function HighlightButton() {
const [on, setOn] = React.useState(false);
return (
<button
className={on ? 'highlight' : ''}
onClick={() => setOn(!on)}
>
{on ? 'Remove Highlight' : 'Add Highlight'}
</button>
);
}
Разница по признакам: в императивном варианте состояние (класс и текст) хранится в DOM, и мы правим его руками; в React состояние on живет в компоненте, а разметка — функция от него. Глядя на return, сразу видно, каким будет интерфейс в каждом из двух состояний.
Парадигмы внутри подходов
Императивный и декларативный — это верхний уровень. Внутри выделяют более узкие стили (подпарадигмы).
Императивные:
- Процедурное — код делится на процедуры и функции, состояние — в переменных. Типичный пример — язык C.
- Объектно-ориентированное (ООП) — данные и поведение упакованы в объекты, методы которых меняют состояние объекта. Основа Java и C++. ООП обычно относят к императивному семейству, потому что объекты хранят и изменяют состояние.
Ближе к декларативному семейству:
- Функциональное — программа строится из выражений и функций без изменения общего состояния (map, filter, reduce — как раз оттуда). Его часто относят к декларативному стилю; это упрощение: степень «чистоты» зависит от языка (в Haskell строже, в JavaScript и Python функциональный стиль соседствует с императивным).
- Логическое — вы задаете факты и правила, а вывод ищет система (язык Prolog).
Большинство массовых языков — мультипарадигменные: Python, JavaScript, C# позволяют писать и императивно, и декларативно. Поэтому корректнее говорить о стиле кода, а не жестко клеить «язык X — только императивный». Даже у декларативных инструментов под капотом лежат императивные реализации (у SQL есть и процедурные расширения, например PL/pgSQL).
Таблица сравнения
| Признак | Императивный подход | Декларативный подход |
|---|---|---|
| Что описываем | последовательность шагов (как) | желаемый результат (что) |
| Состояние | заводим и меняем явно | обычно не меняем напрямую |
| Управление потоком | пишем сами (циклы, условия) | берет на себя исполнитель или движок |
| Языки и инструменты | C, ассемблер, ядро Java/C++ | SQL, HTML, CSS, Prolog |
| Подпарадигмы | процедурное, ООП | функциональное, логическое |
| Сильная сторона | контроль над каждым шагом, наглядная механика | короче, читаемее, меньше ошибок состояния |
| Слабая сторона | многословно, легче ошибиться в состоянии | меньше контроля над «как», сложнее ручной тюнинг |
Признак выбора простой: если важен полный контроль над шагами и производительностью узкого места — берите императивный стиль; если важнее краткость, читаемость и меньше ручного состояния — декларативный. На практике их смешивают: бизнес-логику часто пишут декларативно, а критичный по скорости участок — императивно.
Выводы
- Императивный стиль отвечает на вопрос «как» (шаги и изменение состояния), декларативный — на вопрос «что» (описание результата); способ достижения берет на себя исполнитель.
- Один и тот же результат (сумма квадратов четных = 56) выражается обоими стилями на одном языке — разница в том, пишете вы цикл сами или описываете итог.
- SQL, HTML и React декларативны: вы объявляете нужные данные, структуру или вид интерфейса, а перебор, отрисовку и обновление DOM выполняет движок.
- Внутри императивного лежат процедурное и ООП, ближе к декларативному — функциональное и логическое; отнесение функционального к декларативному — упрощение, зависящее от языка.
- Большинство языков мультипарадигменны, поэтому выбирают стиль под задачу, а не «навсегда»: контроль — императивно, краткость и меньше состояния — декларативно.
Где применяется / связь с практикой
Освойте тему на практике
Оба стиля вы встретите с первых недель практики: цикл и условие — это императивный код, а map, генератор списка или SQL-запрос — декларативный. Научиться осознанно переключаться между ними проще на языке, который поддерживает оба, — например, на Python. Системно разобрать базовый синтаксис, циклы, функции и переход к декларативным конструкциям помогает курс Python Basic. Посмотреть формат занятий и разобрать тему вживую можно на открытых уроках до старта обучения.
Смежные темы: Объектно-ориентированное программирование, Модульное программирование, Программирование на C: базовые знания.
FAQ
Функциональное программирование — это то же самое, что декларативное?
Не совсем. Функциональное часто относят к декларативному семейству за упор на выражения без изменения состояния, но это упрощение: строгость зависит от языка, и функциональный код может соседствовать с императивным (как в JavaScript или Python).
Какой стиль работает быстрее?
Однозначного ответа нет. Императивный код дает контроль над шагами и позволяет вручную оптимизировать узкое место, но декларативный движок (например, оптимизатор SQL) нередко подберет план лучше ручного. Скорость определяется задачей, объемом данных и реализацией, а не самим стилем.
Что новичку учить первым — императивный или декларативный стиль?
Обычно сначала осваивают императивные основы (переменные, циклы, условия): они делают механику видимой. Декларативные конструкции (генераторы, map/filter, SQL) естественно добавляются следом, когда понятно, что именно они прячут внутри.



