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

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

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

Парадигма и язык — это разные вещи

Частая путаница: «Python — императивный язык», «SQL — декларативный язык». Точнее говорить о парадигме, а не о языке целиком. Большинство современных языков мультипарадигменные: на них можно писать в разных стилях.

Python поддерживает и императивный стиль (циклы, присваивания), и функциональный (map, генераторы), и ООП (классы). JavaScript — тоже. Чистых представителей одной парадигмы немного: SQL в основном декларативный, Haskell в основе функциональный, Prolog логический.

Поэтому корректная формулировка — «этот код написан в императивном стиле», а не «этот язык императивный». Язык лишь дает средства для того или иного подхода.

Императивный подход: пишем последовательность шагов

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

Аналогия — подробный рецепт: включи плиту, разбей яйца, вылей на сковороду, жарь до корочки. Каждый пункт — команда, порядок важен.

Посчитаем сумму четных чисел в списке императивно — заводим накопитель и проходим цикл:

numbers = [1, 2, 3, 4, 5]
total = 0
for n in numbers:
    if n % 2 == 0:
        total += n
print(total)  # 6

Мы сами управляем: создаем переменную total, перебираем элементы, проверяем условие, меняем состояние. Это и есть «как».

Внутри императивной парадигмы обычно выделяют два стиля.

Процедурный — код организован в процедуры и функции, которые вызывают друг друга и работают с общими данными. Классические примеры такого стиля — C, ранний Pascal.

Объектно-ориентированный (ООП) — данные и работающие с ними операции объединяются в объекты; программа — это взаимодействие объектов через их методы. ООП чаще относят к императивному семейству, потому что методы обычно меняют состояние объекта. Примеры языков с сильной ООП-поддержкой: Java, C#, C++.

Декларативный подход: описываем результат

Декларативное программирование — парадигма, где вы описываете что нужно получить, а способ вычисления берет на себя исполнитель (движок БД, интерпретатор, среда выполнения). Явного пошагового алгоритма в коде нет.

Аналогия к тому же рецепту: вместо списка действий вы говорите «приготовь яичницу» — как именно жарить, повар решает сам.

Ту же сумму четных чисел на SQL мы не считаем руками — описываем, какой результат хотим, а как обойти строки, решает СУБД:

SELECT SUM(value) AS total
FROM numbers
WHERE value % 2 = 0;

Здесь нет цикла и накопителя: мы задали условие отбора и агрегат, а план выполнения строит база.

Декларативный стиль возможен и в обычном языке. В Python то же самое компактно выражается через генераторное выражение — мы описываем результат, а не механику обхода:

numbers = [1, 2, 3, 4, 5]
total = sum(n for n in numbers if n % 2 == 0)
print(total)  # 6

Оба варианта дают 6, но второй ближе к декларативному стилю: мы не заводим счетчик и не пишем тело цикла вручную.

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

Функциональное — вычисление строится как композиция функций, без изменяемого состояния и с упором на неизменяемые данные. Примеры: Haskell, а также функциональные средства в Python, JavaScript, Scala.

Логическое — вы описываете факты и правила, а система выводит ответ через логический вывод. Самый известный представитель — Prolog. Такой стиль встречается редко, в основном в задачах на правила и вывод.

Императивный и декларативный подходы: сравнение

Признак Императивный подход Декларативный подход
Что описываем Как получить результат (шаги) Какой результат нужен
Состояние и переменные Активно меняются Обычно избегаются, данные неизменяемы
Кто управляет порядком Программист явно Исполнитель (движок, интерпретатор)
Читаемость крупной логики Дольше вникать в «как» Короче, если движок умеет нужное
Контроль над деталями Полный Ограничен возможностями исполнителя
Типичные представители C, Java, процедурный и ООП-код SQL, Haskell, Prolog, HTML-разметка

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

Отдельно стоит отметить: HTML и CSS — это языки разметки и описания, а не полноценные языки программирования (в них нет привычной алгоритмической логики). Их относят к декларативным как пример «описываем результат»: тегами задается структура страницы, а как ее нарисовать — решает браузер.

Как выбрать подход под задачу

Ориентируйтесь на характер задачи, а не на моду:

  1. Нужен точный контроль над шагами, память, производительность — императивный стиль (системное ПО, алгоритмы, драйверы).
  2. Работаете с данными в БД — декларативный SQL почти всегда удобнее ручного перебора.
  3. Много преобразований коллекций, хочется меньше побочных эффектов — функциональные приемы поверх вашего языка.
  4. Строите большую предметную модель с состоянием — ООП.

На практике подходы смешивают в одном проекте: бизнес-логика в ООП, выборки в SQL, обработка списков функциональными средствами. Это норма, а не противоречие.

Выводы

  • Парадигма — это способ описать решение; императивный отвечает на вопрос «как», декларативный — «что».
  • Парадигма и язык — не одно и то же: большинство языков мультипарадигменные, стиль задает не язык, а код.
  • Процедурный и ООП обычно относят к императивному семейству, функциональный и логический — к декларативному.
  • SQL и HTML-разметка — привычные примеры декларативного описания результата.
  • Выбор подхода зависит от задачи, и в реальных проектах их спокойно комбинируют.

Где применяется / связь с практикой

Разобраться в парадигмах проще всего на языке, где доступны сразу несколько стилей. Python как раз такой: на нем пишут и обычные императивные циклы, и компактные генераторы в декларативном духе, и классы для ООП. Если хотите не только прочитать про виды программирования, но и почувствовать разницу руками, начните с основ синтаксиса и структур данных.

Освойте тему на практике

С нуля собрать эту базу помогает курс Python-разработчик. Basic: на нем разбирают переменные, циклы, функции и работу с коллекциями — то самое, из чего складываются императивный и функциональный стили.

Освойте тему на практике

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

FAQ

ООП — это отдельная парадигма или часть императивной?
Чаще ООП относят к императивному семейству, поскольку методы объектов меняют их состояние. При этом ООП можно рассматривать как самостоятельный принцип организации кода, ортогональный делению на «как» и «что».

Можно ли на Python писать декларативно?
Да, частично. Генераторные выражения, map, filter и работа с неизменяемыми данными приближают код к декларативному стилю, хотя сам язык остается мультипарадигменным.

Является ли SQL полноценным языком программирования?
SQL — специализированный декларативный язык запросов к базам данных. Классических алгоритмических конструкций в базовом SQL нет, но диалекты (например, PL/pgSQL, T-SQL) добавляют процедурные расширения.

OTUS Журнал
Скидка 5% 14-20 сентября на курсы (popup)