Чем отличаются данные от программы декларативная

bestprogrammer.ru

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

Изучение

На чтение 9 мин Просмотров 1.8к. Опубликовано 27.07.2022

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

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

Отличия императивного и декларативного программирования

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

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

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

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

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

Другими словами, вас интересует, как работает программа, и вы даете ей четкие инструкции. Проиллюстрируем это на примере псевдокода.

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

Begin Accept location from user input of either location name or ZIP code. Call OpenWeather’s Geocoding API to convert location data into geographic coordinates. Call OpenWeather’s Current Weather Data API. Send geographic coordinates to OpenWeather. Call OpenWeather’s Daily Forecast 16 Days API.

Resend geographic coordinates. Parse JSON returned by the APIs to extract current weather and forecast data. Return current weather and forecast. Display current weather and forecast to user. End

В этом простом примере императивные инструкции определяют, что должно делать приложение, когда это делать и как это делать. Этот псевдокод сравним с императивным программированием, с помощью которого вы создаете логику программы, создавая операторы цикла, вызывая функции и т. д., и все это в определенном порядке.

Чем различаются императивное и декларативное программирование? Душкин объяснит

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

Поддержка обеих парадигм

На самом деле вы можете использовать Python как в декларативном, так и в императивном программировании. За прошедшие годы некоторые другие императивные языки также получили обновления, позволившие им поддерживать программирование в декларативном стиле. К ним относятся JavaScript, C++ и C#.

В частности, за последние годы в C++ было внесено несколько улучшений, многие из которых сделали C++ более декларативным. Например, более новые версии C++ имеют стандартную библиотеку шаблонов (STL), которая предоставляет четыре компонента: алгоритмы, контейнеры, функции и итераторы.

Среди этих компонентов есть несколько встроенных функций или операций, которые ранее выполнялись вручную, например std::sortи std::list. Теперь вы можете легко использовать std::sortи продолжать кодирование без необходимости разработки императивного алгоритма сортировки.

Следующий пример кода демонстрирует эту функцию в действии:

Источник: bestprogrammer.ru

Можно ли использовать декларативный и императивный стили написания программ одновременно?

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

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

Читайте также:
Вариативная часть учебной программы это

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

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

Данная статья — размышление о совместимости декларативной и императивной парадигм программирования и возможности их одновременного использования в рамках одного языка программирования одновременно.

Что такое «Декларативное программирование»?

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

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

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

Уже в изначальном определении закладывается противопоставление парадигм, а дальше идут рассуждения о «направлении» программирования. И хоть вики сама и не является авторитетным источником информации, но даже такая заготовка статьи смогла показать направление поиска ответов на первый поставленный вопрос.

И заставил задуматься один абзац в конце статьи следующего содержания:

«Чисто декларативные» компьютерные языки зачастую неполны по Тьюрингу — так как теоретически не всегда возможно порождение исполняемого кода по декларативному описанию. Это иногда приводит к спорам о корректности термина «декларативное программирование» (менее спорным является «декларативное описание решения» или, что то же самое, «декларативное описание задачи»).

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

Например в языке Prolog, который обычно и приводят в качестве примера декларативного языка программирования, «замаскированным» императивным оператором является знак вопроса. Он кажется естественным и логичным, как же без него? Но по своей сути, это императивная конструкция!

Тоже самое касается и языка SQL. Он тоже как бы декларативный, но неожиданно все его команды являются императивными по сути. SELECT, CREATE, ALTER, DROP, INSERT, UPDATE, DELETE и т. д., а декларативными являются только описания условий их выполнения!

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

А что отличает декларативные языки программирования от императивных?

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

Интересно, а является ли внутренняя система поиска решений обязательным признаком декларативного стиля программирования или это только особенность конкретного языка программирования, которая не зависит от декларативного стиля написания кода?

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

А заодно, таким образом можно будет и изучить вопрос, получится ли написать программу в декларативном стиле используя обычный императивный язык программирования?

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

parent(«Tom»,»Jake»). parent(«Janna»,»Jake»). parent(«Tom»,»Tim»). male(«Tom»). male(«Tim»). male(«Jake»). female(«Janna»). brother(X,Y):-parent(Z,X),parent(Z,Y),male(X),male(Y),X=Y. ? brother

Получилась вот такая функционально — эквивалентная программа на С++, которая максимально приближена по стилю к декларативному прототипу:

enum sex_ < male, female >; struct human; typedef std::vector parent_; struct human < const char *name; sex_ sex; parent_ parent; >; human Tom>; human Janna>; human Jake>; human Tim>; std::vector humans; auto brothers = [](human * a, human * b) < auto intersec = [](parent_ b) < for (auto elem_a : a) < for (auto elem_b : b) < if(elem_a elem_b elem_a == elem_b) < return true; >> > return false; >; return a b a != b a->sex == male b->sex == male (intersec(a->parent, b->parent)); >; for (auto a : humans) < for (auto b : humans) < if(brothers(a, b)) < std::cout name name > >

Читайте также:
Программа как Плей Маркет на Андроид

Конечно, текст на С++ получается значительно многословней, чем вариант на Прологе, но по сути, это почти дословное повторение декларативного стиля написания кода. Тем более, не стоит забывать про рассуждения в начале статьи об изначальном выборе концепции при создании языка и «принуждении» программистов пользоваться только одной, изначально выбранной парадигмой разработки.

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

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

Но если это так, то что мешает попробовать разработать синтаксис языка программирования, в котором можно было бы использовать сразу императивный и декларативный стили программирования одновременно?

Что мешает совместить императивный и декларативный стили написания в рамках одной программы?

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

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

А декларативный стиль написания программ стал появляться только после создания высокоуровневых языков программирования. И основная цель создания данных языков сместилась на поиск решения конечного пользователя, а не на упрощение генерации бинарных файлов с машинными инструкциями. Если внимательно посмотреть на приведенные выше примеры кода, то можно заметить, что в них определения данных и операторы для их обработки идут вперемешку, (для примера на С++ это определение лямбд функции), что кардинально отличается от императивного подхода.

Так может быть, основная особенность декларативного стиля как раз и заключается в том, что в нем не разделяются «данные» и «действия над данными»? Или как вариант, можно не указывать выполняемые действия над данными вовсе (как в некоторых SQL конструкциях)?

Может быть как раз именно эта особенность (возможность последовательной записи программного кода в соответствии с собственными логическими рассуждениями, в которых могут перемежаться «данные» и «функции», как это происходит при человеческом мыслительном процессе), не дает в полной мере реализовать возможность совмещения императивных и декларативных стилей программирования?

И если это так, тогда можно попробовать разработать такой синтаксис, который будет поддерживать определение как данных, так и декларацию функций в рамках единого потока языковых конструкций!

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

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

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

В результате, условный оператор получился практически математический, который легко объединяется в последовательности для реализации проверки множественных условий вида «else if». А для объединения сразу нескольких логического операторов между собой и для отделения их от последующего действия, операторы проверки условия можно заключать в круглые скобки.

Читайте также:
Программы которые не изменяют файлы на дисках

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

условие -> действие; или (условие) -> ; или (условие1 || условие2) -> -> ;

Или расширенный вариант, для наглядности записанный с отступами:

(условие1) -> (условие2) -> (условие3) -> -> ;

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

(условие) ;

счетный цикл для работы с итератором*:
(счетчик_или_данные!)? ;

*) Разъяснение операторов «итератор» приводится в этой статье

В этом случае, решение тестового примера декларативной программы на Прологе можно будет легко оформить, как в императивном, так и в декларативном стилях одновременно!

Примерно это и требовалось показать!

З.Ы.

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

З.З.Ы

В комментариях gbg привел очень простой ответ на один из поднятых вопросов. Причем в более элегантном виде и без написания кода!

Ну и пять копеечек про ООП. Как ни странно:

1) В нем таки есть декларативная часть, все эти pubic, private, virtual, etc
2) Эта декларативная часть, внезапно, элегантно позволяет реализовывать декомпозицию и управление сложностью.
3) При наличии перегрузок, можно поиграть в алгебраическое мышление, рассматривая взаимодействие двух объектов как бинарную операцию.

Ух ты, ООП — это обкатанная практикой технология, которая совмещает декларатив с императивом и вроде позволяет освоившим ее вкусно кушать и мягко спать!

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

Источник: habr.com

Декларативный подход к программированию

Декларативный подход к программированию что такое

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

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

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

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

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

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

Декларативные языки пытаются решить эту проблему. Переменные в них используются очень экономно, потому что значения чаще всего передаются в виде возвращаемого значения определенной функции. Декларативные языки также не включают средства для выполнения цикла, известного как do-while или for. Все решается рекурсией .

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

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

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

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

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

Другая группа языков, классифицируемых как декларативные языки, — это предметно-ориентированный язык программирования или языки для решения конкретной проблемы.

Эти языки, как правило, неполные тюрингские . Примерами являются SQL для управления данными в базе данных, регулярные выражения или XSL для управления данными XML.

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

Вывод:

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

Источник: prognote.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru