Light-electric.com

IT Журнал
4 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

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

Основные принципы программирования: императивное и декларативное программирование

    Переводы, 26 января 2017 в 17:41

Рассказывает Тайлер МакГиннис, Google Developer Expert

Вы наверняка слышали о таких понятиях, как императивное и декларативное программирование, и скорее всего гуглили определения. И поэтому вы наверняка видели что-то подобное: “Императивное программирование — это описание того, как ты делаешь что-то, а декларативное — того, что ты делаешь. Это объяснение отлично подходит тем, кто уже разобрался в этом вопросе — но не новичкам.

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

Допустим, вы поняли, что слишком много времени уделяли работе, и решили пригласить свою половинку на свидание. Вы пришли в ресторан, подошли к администратору и сказали…

Императивный подход (как): Я вижу, что тот угловой столик свободен. Мы пойдём туда и сядем там.

Декларативный подход (что): Столик для двоих, пожалуйста.

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

Я задам вам вопрос и хочу, чтобы вы придумали и императивный, и декларативный подход.

“Я у Ашана. Как мне пройти до твоего дома?”

“Пройди через северный выход парковки и поверни налево. Сядь на автобус 678 и выйди на остановке “Улица Победы”. Поверни направо, как если бы ты шёл в Икею. Иди прямо и поверни направо у первого светофора. На следующем светофоре поверни налево. Номер моего дома — 134.”

Мой адрес: Энск, улица Победы, дом 134.

Неважно, как я попаду к твоему дому, важно, на какой машине я приеду. У неё будет или императивная механическая КПП, или декларативная автоматическая КПП. Достаточно метафор?

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

Итак, я повторюсь: многие (если не все) декларативные подходы имеют слой неких императивных абстракций.

Теперь мы перейдём от приятных метафор к реальному коду. Сперва посмотрим, какие языки являются декларативными, а какие — императивными:

  • Императивные: C, C++, Java.
  • Декларативные: SQL, HTML.
  • Смешанные (могут быть таковыми): JavaScript, C#, Python.

Вот типичные примеры на SQL и HTML:

Достаточно взглянуть на них, чтобы понять, что происходит. Они декларативны, заявляя, что должно быть сделано, а не как. Вы описываете желаемый результат, не углубляясь в инструкции. Неважно, как будут выбраны пользователи из Мексики. Неважно, как браузер распарсит ваш article . Важно, что вы получите мексиканских пользователей и новый header и paragraph на сайте.

Пока неплохо. Давайте рассмотрим примеры на JavaScript.

Представьте, что вы на собеседовании. Откройте консоль и ответьте на следующие вопросы.

  1. Напишите функцию, называющуюся double , которая принимает массив чисел и возвращает новый массив, каждый элемент которого в два раза больше входного: double([1,2,3]) -> [2,4,6] .
  2. Напишите функцию, называющуюся add , которая принимает массив и возвращает сумму всех его элементов: add([1,2,3]) -> 6 .
  3. Используя jQuery (или чистый JavaScript), добавьте обработчик события click к элементу с id , равным btn . По нажатию переключите класс highlight и смените текст на Add Highlight или Remove Highlight , в зависимости от текущего состояния элемента.

Давайте взглянем на самые распространённые подходы к решению этих задач, которые являются императивными.

Разобравшись, что общего у этих императивных примеров, мы поймём, что именно делает их императивными.

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

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

Заметьте, что в первых двух примерах я использовал встроенные методы JavaScript, map и reduce . Как видите, декларативные решения вновь оказались абстракциями над императивными реализациями. Но нас не интересует, как реализованы эти методы. Мы также не изменяем состояния, да и читается этот код лучше.

Ну а третий? В нём я немного схитрил, использовав React — но обратите внимание, что все три императивные ошибки исправлены. React замечателен тем, что в нём вы можете создавать декларативные пользовательские интерфейсы. Смотря на компонент Btn, сразу понятно, как будет выглядеть интерфейс. Кроме того, состояния «живут» не в DOM, а в самом React-компоненте.

Читать еще:  Язык программирования c реферат

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

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

Войти

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

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

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

Чистые функциональные языки типа F# существуют, но их область применения ограничена. Как минимум, функция ввода данных от пользователя не является чистой (результат вычисления зависит только от параметров). Она возвращает каждый раз разные значения, не зависящие от входных параметров. Поэтому речь идет лишь о поддержке функциональных возможностей в традиционных языках. Так в C# поддерживаются анонимные функции, лямбда-выражения, итераторы, LINQ. Анонимные функции и итераторы также доступны в PHP и JavaScript. Всех этих возможностей уже достаточно, чтобы привести часть программы к декларативному виду.

Итак две противоположности

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

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

Базовой операцией при декларативном подходе является операция над множеством или над всеми элементами множества. Причем для последнего случая порядок обработки не важен, так как обрабатывающая функция должна быть чистой. В C#, PHP, Java, Javascript множество реализуется как массив или последовательность, генерируемая итератором. Ниже пример сравнения двух подходов на C#

WebDev → Императивное vs Функциональное программирование

Парадигма — это стиль написания исходного кода компьютерной программы. Существует несколько парадигм.

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

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

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

  • именованных переменных;
  • оператора присваивания;
  • составных выражений;
  • подпрограмм;
  • циклов.

К подвидам императивного программирования относят Процедурное и Объектно-ориентированное программирование (ООП).

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

К подвидам декларативного программирования относят Функциональное и Логическое программирование.

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

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

  • функции первого класса (можно передавать как аргументы и возвращать из других функций);
  • функции высшего порядка (принимают на вход другие функции);
  • рекурсии;
  • состояние никогда не меняется;
  • не используется присваивание.

Функциональное программирование — это программирование значениями. Функциональный подход к программированию отличается от императивного отсутствием внутренних состояний. В функциональном программировании отсутствует присваивание как способ изменения значения.

Вы можете видеть в функциональных языках использование знака =, но в функциональных языках он оно называется “связывание“. Мы не изменяем никаких переменных, мы просто даем имя (алиас) какому-то выражению и потом обращаемся к этому выражению через это имя.

Основой для функционального программирования являются Лямбда-исчисления, многие функциональные языки можно рассматривать как «надстройку» над ними.

Лямбда-функции — это функции, у которой фактически нет имени. Лямда-выражения — анонимные функции. Понятие пришло из математики, где использовалась специальная форма записи функций, ликвидирующая неоднозначности функция/значение функции и пр.

Читать еще:  Обучение программированию c

Примеры языков
Императивные: Ruby, PHP, Python, C++, C#, Java, JavaScript, Swift и т.д.
Функциональные: Haksell, Erlang
Логические: Prolog
Мультипарадигменные: Clojure, Ocaml, Scale, F#

Функционально программировать можно практически в любом языке программирования.

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

Выводы

Еесли кратко: императивная — манипулирование состоянием; декларативная парадигма — отсутствие состояния.

В общем и целом, декларативное программирование идет от человека к машине, тогда как императивное — от машины к человеку.

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

Или насколько неверным было мое представление о React

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

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

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

Согласно этой и этой информации:

Декларативное программирование — это парадигма программирования … которая выражает логику вычисления без описания его потока управления.
Императивное программирование — это парадигма программирования, в которой используются утверждения, которые изменяют состояние программы.

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

Прежде чем я зайду слишком далеко, хочу подчеркнуть, что нет ничего плохого в любом из этих подходов. У каждого есть сильные и слабые стороны, но один подход — всегда правильно. Например, декларативное программирование может привести к меньшему прямому контролю, что может быть неверным для таких приложений, как встроенные системы, где «правильный ответ, полученный слишком поздно, становится неправильным ответом».

Хорошо, вот метафора.

Декларативное программирование — это как попросить вашего друга нарисовать пейзаж. Тебе все равно, как он рисует, это зависит от него.

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

Продемонстрируй в коде

Ладно, ладно, вот несколько примеров кода. У нас есть кнопка, которая меняет цвет при нажатии. Я начну с императивного примера:

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

Возможно, различия незначительны. У нас по-прежнему есть логика, которая говорит: если красный, значит синий, но есть одна огромная разница. Пример c React никогда не затрагивает элемент. Он просто объявляет, что элемент должен отображаться с учетом нашего текущего состояния (далее — state). Он фактически не манипулирует самим DOM.

Использование прямого манипулирования DOM является ошибкой, которую я часто делал, когда впервые начал работать с React. Я заметил, что это тоже является проблемой для разработчиков, у которых большой опыт в jQuery.

При написании React зачастую нужно думать не о том, как вы хотите достичь результата, а об внешнем виде компонента с его новым state. Это заставляет нас хорошо контролировать поток, где state проходит через серию предсказуемых и воспроизводимых мутаций. Это относится не только к компонентам, но и к state самого приложения. Библиотеки, такие как Redux, могут помочь реализовать этот архитектурный подход, но они не обязательны для достижения этой цели.

Для меня структура приложения является наиболее важным аспектом, когда вы хотите использовать декларативный подход. Ему легко следовать на одном компоненте, но тяжелее при масштабировании приложения. Заманчиво заставить два компонента взаимодействовать друг с другом с помощью хаков или согласиться на передачу информации только наполовину. Но последовательный подход к управлению state упростит ваше приложение в целом.

Чего следует избегать

Я либо допустил, либо позволил допустить все эти ошибки в коде, над которым работал. Это всего лишь советы.

  • Избегайте refs. Конечно, иногда они необходимы, но если вы чувствуете, что подбираетесь к refs, это часто означает, что вы делаете что-то неправильно. (В документации React указаны некоторые уместные способы использования refs).
  • Попытка манипулировать DOM напрямую (это очень тесно связано с Refs)
  • Вместо возвращения функций, которые рендерят компонент, лучше возвращайте функции, которые возвращают необходимую информацию для отображения компонента. В первом случае мы указываем, что делать (отобрази именно это), а во втором -возвращаем некоторую информацию (используйте эту информацию, чтобы что-то сделать).
  • Общение между siblings, а не через компоненты. Постарайтесь общаться только с другими компонентами через props.
  • Используйте чистые функциональные компоненты где это возможно. Поскольку эти компоненты не имеют методов жизненного цикла, они требуют, чтобы вы полагались на декларативный, основанный на props подход. Они также могут повысить производительность.
Читать еще:  Программирование сети c

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

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

Императивные языки программирования противопоставляются функциональным и логическим языкам программирования. Функциональные языки, например, Haskell, не представляют собой последовательность инструкций и не имеют глобального состояния. Логические языки программирования, такие как Prolog, обычно определяют что надо вычислить, а не как это надо делать.

Содержание

История

Первыми императивными языками были машинные коды — родной язык программирования для компьютера. В этих языках инструкции были крайне просты, что снижало нагрузку на компьютеры, однако затрудняло написание крупных программ. В 1954 появился первый «человеческий» язык программирования — FORTRAN, разработанный Джоном Бэкусом в IBM. FORTRAN является компилируемым языком программирования и позволяет использовать именованные переменные, составные выражения, подпрограммы и многие другие элементы распространённых сейчас императивных языков. В конце 1950х годов с целью упростить выражение математических алгоритмов был разработан ALGOL; в дальнейшем он послужил базой для написания операционных систем для некоторых моделей компьютеров. COBOL (1960) и BASIC (1964) являлись первыми попытками сделать программирование более похожим на обычный английский язык. В 1970х годах Никлаус Вирт разработал язык Pascal. Язык C был создан Денисом Ритчи. Команда разработчиков из Honeywell начала разработку языка Ada в 1978, и через четыре года опубликовала требования для его работы. Спецификация увидела свет в 1983 и была обновлена в 1995 и 2005/6 годах.

В 1980х резко возрос интерес к объектно-ориентированному программированию. Smalltalk-80, впервые разработанный Аланом Кэем в 1969, был обновлён в 1980 исследовательским центром Xerox PARC. По образу и подобию языка Simula (предположительно, первого в мире ООП-языка, разработанного ещё в 1960х) Бьерн Страуструп разработал C++, основанный на C. C++ был впервые реализован в 1985. В 1987 Ларри Уолл выпустил язык Perl; Python был выпущен в 1990 Гвидо ван Россумом; в 1994 Расмус Лердорф разработал PHP; Java был разработан в Sun Microsystems в 1994; Ruby был выпущен в 1995; C# был зачат в декабре 1998. В 2002 — система .NET Framework, объединяющая многие языки.

См. также

Литература

  • Роберт В Себеста Основные концепции языков программирования = Concepts of Programming Languages. — 5-е изд. — М .: «Вильямс», 2001. — С. 672. — ISBN 0-201-75295-6
  • Terrence W. P., Zelkowitz M. V. Programming Languages: Design and Implementation. — 3. — Prentice Hall, 1996.

Ссылки

  • Императивное программирование в обзоре парадигм программирования Д. Петрова
  • Оперативное конструирование программ в императивных языках программирования

  • Проставив сноски, внести более точные указания на источники.

Wikimedia Foundation . 2010 .

Смотреть что такое «Императивное программирование» в других словарях:

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

ИМПЕРАТИВНОЕ ПРОГРАММИРОВАНИЕ — Парадигма программирования, которая, в отличие от декларативного программирования, описывает процесс вычисления в виде инструкций, изменяющих состояние программы. Императивная программа очень похожа на приказы, выражаемые повелительным… … Словарь бизнес-терминов

Императивное параллельное программирование — методология программирования, в которой предлагается использование явных конструкций для параллельного исполнения выбранных фрагментов программ. См. также: Императивное программирование Финансовый словарь Финам … Финансовый словарь

Программирование в ограничениях — Парадигмы программирования Агентно ориентированная Компонентно ориентированная Конкатенативная Декларативная (контрастирует с Императивной) Ограничениями Функциональная Потоком данных Таблично ориентированная (электронные таблицы) Реактивная … Википедия

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

Реактивное программирование — Парадигмы программирования Агентно ориентированная Компонентно ориентированная Конкатенативная Декларативная (контрастирует с Императивной) Ограничениями Функциональная Потоком данных Таблично ориентированная (электронные таблицы) Реактивная … Википедия

Процедурное программирование — Статья противоречит другой статье Данная статья, по видимому, противоречит другой статье (en:Procedural programming). Страница обсуждения может содержать подробности … Википедия

Субъектно-ориентированное программирование — Парадигмы программирования Агентно ориентированная Компонентно ориентированная Конкатенативная Декларативная (контрастирует с Императивной) Ограничениями Функциональная Потоком данных Таблично ориентированная (электронные таблицы) Реактивная … Википедия

Парадигма — (Paradigm) Определение парадигмы, история возникновения парадигмы Информация об определении парадигмы, история возникновения парадигмы Содержание Содержание История возникновения Частные случаи (лингвистика) Управленческая парадигма Парадигма… … Энциклопедия инвестора

Императивный язык программирования — Процедурное (императивное) программирование является отражением архитектуры традиционных ЭВМ, которая была предложена фон Нейманом в 40 х годах. Теоретической моделью процедурного программирования служит алгоритмическая система под названием… … Википедия

Ссылка на основную публикацию
ВсеИнструменты
Adblock
detector
×
×