В чем разница между декларативным и императивным программированием?

Я искал в Интернете поиски определения декларативного и императивного программирования, которое бы пролило свет на меня. Тем не менее, язык, используемый в некоторых ресурсах, которые я нашел, устарел - например, в Википедии. У кого-нибудь есть реальный пример того, что они могли бы показать мне, что могло бы дать некоторую перспективу этой теме (возможно, в C#)?

23 ответа

Решение

Отличным примером декларативного и императивного программирования на C# является LINQ.

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

Например, давайте начнем с этой коллекции и выберем нечетные числа:

List<int> collection = new List<int> { 1, 2, 3, 4, 5 };

С императивным программированием мы должны были пройти через это и решить, чего мы хотим:

List<int> results = new List<int>();
foreach(var num in collection)
{
    if (num % 2 != 0)
          results.Add(num);
}

Здесь мы говорим:

  1. Создать коллекцию результатов
  2. Пройдите по каждому номеру в коллекции
  3. Проверьте число, если оно нечетное, добавьте его к результатам

С другой стороны, в декларативном программировании вы пишете код, который описывает, что вы хотите, но не обязательно, как его получить (объявляйте желаемые результаты, но не пошагово):

var results = collection.Where( num => num % 2 != 0);

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

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

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

Простой пример в Python:

# Declarative
small_nums = [x for x in range(20) if x < 5]

# Imperative
small_nums = []
for i in range(20):
    if i < 5:
        small_nums.append(i)

Первый пример является декларативным, потому что мы не указываем никаких "деталей реализации" построения списка.

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

Одним из преимуществ декларативного программирования является то, что оно позволяет компилятору принимать решения, которые могут привести к лучшему коду, чем то, что вы могли бы сделать вручную. Запуск с примером SQL, если у вас был такой запрос

SELECT score FROM games WHERE id < 100;

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

Декларативный и императивный

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

Декларативное программирование: это парадигма программирования, которая выражает логику вычислений (что делать) без описания потока управления (как это делается). Некоторые хорошо известные примеры декларативных доменных языков (DSL) включают CSS, регулярные выражения и подмножество SQL (например, запросы SELECT). Многие языки разметки, такие как HTML, MXML, XAML, XSLT... часто являются декларативными. Декларативное программирование пытается стереть различие между программой как набором команд и программой как утверждением о желаемом ответе.

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

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

В следующем примере императивного программирования в MSDN, циклы по номерам от 1 до 10, и находит четные числа.

var numbersOneThroughTen = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//With imperative programming, we'd step through this, and decide what we want:
var evenNumbers = new List<int>();
foreach (var number in numbersOneThroughTen)
{    if (number % 2 == 0)
    {
        evenNumbers.Add(number);
    }
}
//The following code uses declarative programming to accomplish the same thing.
// Here, we're saying "Give us everything where it's odd"
var evenNumbers = numbersOneThroughTen.Select(number => number % 2 == 0);

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

Все вышеперечисленные ответы и другие посты онлайн упоминают следующее:

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

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

  • Например, LINQ более декларативен, чем циклы (for, while и т. Д.), Например, вы можете использовать list.Where(), чтобы получить новый отфильтрованный список. Чтобы это сработало, Microsoft сделала всю тяжелую работу за абстракцию LINQ.

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

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

Наконец, хотя функциональное программирование и LINQ могут сделать вашу программу более декларативной, вы всегда можете сделать ее еще более декларативной, предоставляя больше абстракций. Например:

// JavaScript example

// Least declarative
var bestProducts = [];
for(var i = 0; i < products.length; i++) {
    var product = products[i];
    if (product.rating >= 5 && product.price < 100) {
        bestProducts.push(product);
    }
}


// More declarative
var bestProducts = products.filter(function(product) {
    return product.rating >= 5 && product.price < 100;
});

// Most declarative, implementation details are hidden in a function
var bestProducts = getBestProducts();

Я добавлю еще один пример, который редко появляется в декларативном / императивном программировании: пользовательский интерфейс!

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

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

В декларативном конце у вас есть WPF. Вы в основном пишете какой-то XML (да, да, технически "XAML"), и фреймворк делает всю работу за вас. Вы говорите, как выглядит пользовательский интерфейс. Это зависит от системы, чтобы выяснить, как это сделать.

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

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

Суть всего этого:

Декларативный -> what ты хочешь сделать

Императив -> how ты хочешь это сделать

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


Вы можете посмотреть на каждую часть инструкции как где-то в континууме:

Степень абстракции:

Declarative <<=====|==================>> Imperative

Пример декларативного реального мира:

  1. Библиотекарь, пожалуйста, посмотрите мне копию Моби Дика. (Библиотекарь по своему усмотрению выбирает лучший способ выполнения запроса)

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

  1. Перейти в библиотеку
  2. Система организации поиска книг (Каталог карт - Старая школа)
  3. Узнайте, как использовать карточные каталоги (вы тоже забыли)
  4. Выясните, как полки маркированы и организованы.
  5. Выясните, как книги организованы на полке.
  6. Расположение перекрестной справочной книги из карточного каталога с системой организации, чтобы найти указанную книгу.
  7. Взять книгу в кассу системы.
  8. Проверьте книгу.

Мне понравилось объяснение из кембриджского курса + их примеры:

  • Декларативный - укажите, что делать, а не как это делать
    • Например: HTML описывает, что должно отображаться на веб-странице, а не то, как оно должно быть нарисовано на экране.
  • Обязательно - укажите, что и как
    • int x; - что (декларативно)
    • x=x+1; - как

Императивное программирование требует, чтобы разработчики шаг за шагом определяли, как должен выполняться код. Чтобы дать указания в обязательном порядке, вы говорите: "Идите на 1-ю улицу, поверните налево на улицу Main, проезжайте два блока, поверните направо на Maple и остановитесь в третьем доме слева". Декларативная версия может звучать примерно так: "Поезжай к дому Сью". Один говорит, как что-то сделать; другой говорит, что нужно сделать.

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

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

Calvert, C Kulkarni, D (2009). Essential LINQ. Аддисон Уэсли. 48.

Кража у Филиппа Робертса здесь:

  • Императивное программирование говорит машине, как что-то сделать (в результате чего вы хотите, чтобы это произошло)
  • Декларативное программирование сообщает машине, чего бы вы хотели (и компьютер выясняет, как это сделать)

Два примера:

1. Удвоение всех чисел в массиве

Обязательно следует:

var numbers = [1,2,3,4,5]
var doubled = []

for(var i = 0; i < numbers.length; i++) {
  var newNumber = numbers[i] * 2
  doubled.push(newNumber)
}
console.log(doubled) //=> [2,4,6,8,10]

Декларативно:

var numbers = [1,2,3,4,5]

var doubled = numbers.map(function(n) {
  return n * 2
})
console.log(doubled) //=> [2,4,6,8,10]

2. Суммирование всех элементов в списке

настоятельно

var numbers = [1,2,3,4,5]
var total = 0

for(var i = 0; i < numbers.length; i++) {
  total += numbers[i]
}
console.log(total) //=> 15

Декларативно

var numbers = [1,2,3,4,5]

var total = numbers.reduce(function(sum, n) {
  return sum + n
});
console.log(total) //=> 15

Обратите внимание, что императивные примеры включают создание новой переменной, изменение ее и возвращение этого нового значения (т. Е. Как заставить что-то произойти), тогда как декларативные примеры выполняются для заданного ввода и возвращают новое значение на основе начального ввода (т. Е., что мы хотим, чтобы произошло).

Императивное программирование явно говорит компьютеру, что и как делать, например, указание порядка и т. Д.

C#:

for (int i = 0; i < 10; i++)
{
    System.Console.WriteLine("Hello World!");
}

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

C# является гораздо более императивным языком программирования, но некоторые функции C# являются более декларативными, как Linq

dynamic foo = from c in someCollection
           let x = someValue * 2
           where c.SomeProperty < x
           select new {c.SomeProperty, c.OtherProperty};

То же самое можно написать императивно:

dynamic foo = SomeCollection.Where
     (
          c => c.SomeProperty < (SomeValue * 2)
     )
     .Select
     (
          c => new {c.SomeProperty, c.OtherProperty}
     )

(пример из википедии Linq)

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

С http://en.wikipedia.org/wiki/Declarative_programming

Короче говоря, декларативный язык проще, потому что ему не хватает сложности потока управления (циклы, операторы if и т. д.)

Хорошее сравнение - модель "code-behind" ASP.Net. У вас есть декларативные файлы ".ASPX", а затем императивные файлы кода "ASPX.CS". Я часто обнаруживаю, что если я смогу сделать все, что мне нужно, в декларативной половине сценария, гораздо больше людей смогут следить за тем, что делается.

Императивное программирование
Язык программирования, требующий такой дисциплины, как C/C++, Java, COBOL, FORTRAN, Perl и JavaScript. Программисты, пишущие на таких языках, должны разработать правильный порядок действий для решения проблемы, основанный на знании обработки данных и программирования.

Декларативное программирование
Компьютерный язык, который не требует написания традиционной логики программирования; Пользователи концентрируются на определении ввода и вывода, а не шагов программы, требуемых в процедурном языке программирования, таком как C++ или Java.

Примеры декларативного программирования: CSS, HTML, XML, XSLT, RegX.

Императивное программирование - вы пишете код, который выполняет всю работу

Декларативное программирование - кто-то другой пишет код, выполняющий работу

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

  • Декларативный подход фокусируется на цели конкретного алгоритма, которая часто скрывает сам алгоритм.

  • Императивный подход фокусируется на алгоритме для конкретной цели, который часто скрывает саму цель.

Просто практический пример того, почему CSS является декларативным , а JavaScriptимперативным.

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

      <ul>
  <li class="selected">
    <p>Explore</p>
  </li>
  <li>
    <p>Suggestions</p>
  </li>
</ul>

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

CSS

      li.selected > p {
  color: blue;
}

Здесьобъявляет шаблон элемента, для которого мы хотим свойствоприменяться. В результате «Исследование» выделено синим цветом, а «Предложения» — нет. Обратите внимание, наш код описывает , что мы хотим сделать , а не как. Как механизм выбора CSS находит «Исследовать»? Мы не знаем, и обычно нам все равно.

JavaScript

      let liElements = document.getElementsByTagName("li")
for (let i = 0; i < liElements.length; i++) {
  if (liElements[i].className === "selected") {
    let children = liElements[i].childNodes
    for (let j = 0; j < children. length; j++) {
      let child = children[j]
      if (child.nodeType === Node.ELEMENT_NODE && child.tagName === "P") {
        child.setAttribute("style", "color: blue")
      }
    } 
  }
}

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

Заключение

Каждая парадигма программирования имеет свои преимущества.

CSS (декларативный)

  • лаконичный
  • мы, как программисты, не контролируем, как ядро ​​CSS делает то, что нам нужно. Это дает разработчикам ядра CSS возможность изменить реализацию селектора CSS в любое время. Зачем нужно менять ядро ​​CSS? Возможно, разработчики CSS нашли более быстрый способ применения свойств.

JavaScript (обязательно)

  • настройка. Мы контролируем все аспекты того, как наш код достигает цели.
  • хорош для решения самых разных задач

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

Ознакомьтесь с этой упрощенной версией, чтобы узнать об идемпотенте.

Затем я ввожу определение «ЧТО» и «КАК» , чтобы понять, что на самом деле означают «ЧТО» и «КАК» . В декларативном режиме вы связываете одни данные с другими, определяя отношения между ними. Вы не упоминаете, как эти отношения должны быть достигнуты, а «ЧТО» эти отношения. Через отношения вы описываете «ЧТО» выглядят ваши выходные данные, а не «КАК» для достижения этих выходных данных.

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

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

Эта диаграмма имеет некоторые свойства:

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

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

К настоящему времени декларативный подход может показаться вам ЧИСТЫМ и НЕИЗМЕНИМЫМ (которые обычно используются в функциональном программировании), если да — ХОРОШИМ, а если нет — ОТЛИЧНЫМ. Потому что это не цель здесь, это то, что автоматически возникло из этого шаблона.

Если ваш фрагмент кода можно преобразовать в эту диаграмму, то он полностью декларативен , в противном случае он лежит где-то еще на шкале.

Декларативная близка к математике.

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

Императив вступает в дело. Вот где эта основная работа выполняется. В императиве вы шаг за шагом указываете «КАК» это нужно сделать, и вы знаете, что эта последовательность шагов создаст запрошенную связь между одними данными (входными данными) и другими данными (выходными данными). Здесь вы создаете переменные, изменяете их, перебираете массив и все остальное.

Императив близок к программированию.

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

Теперь давайте возьмем эти 2 примера :

Второй пример можно преобразовать в диаграмму следующим образом:

                 
<--------- <--------- <---------

  • filter_r (отношения): это только четные числа
  • map_r (отношения): все числа, умноженные на 10 из
  • reduce_r (отношения): все числа добавлены из

это должно выглядеть как составная функция математики: reduce_r( map_r( filter_r( d) ) )

В декларативной работе задача разработчика состоит в том, чтобы нарушить конечную цель ( a) на подцели ( b, c), которые помогут достичь конечной цели.

Конечно, под капотом процедур map , reduce и filter выполняется императивное выполнение кода.

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

Ссылки: Purpleidea (Джеймс) , www.dataops.live, wiki.c2.com

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

public static void main(String[] args)
{
    System.out.print("4 = 4.");
}

С другой стороны, императивные предложения на английском языке дают команду или делают какой-то запрос. Таким образом, императивное программирование - это просто список команд (сделайте это, сделайте это). Вот обязательный способ показать, равны ли два числа друг другу или нет при принятии пользовательского ввода, в Java:

private static Scanner input;    

public static void main(String[] args) 
{
    input = new Scanner(System.in);
    System.out.println();
    System.out.print("Enter an integer value for x: ");
    int x = input.nextInt();
    System.out.print("Enter an integer value for y: ");        
    int y = input.nextInt();

    System.out.println();
    System.out.printf("%d == %d? %s\n", x, y, x == y);
}

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

Декларативная программа - это просто данные для ее более или менее "универсальной" императивной реализации /vm.

плюсы: указание только данных в жестко заданном (и проверенном) формате проще и менее подвержено ошибкам, чем непосредственное указание варианта какого-либо императивного алгоритма. некоторые сложные спецификации просто не могут быть написаны напрямую, только в некоторой форме DSL. best и freq, используемые в структурах данных DSL - это наборы и таблицы. потому что у вас нет зависимостей между элементами / строками. и когда у вас нет зависимостей, у вас есть свобода изменения и простота поддержки. (сравните, например, модули с классами - с модулями, которые вам нравятся, и с классами, у которых есть проблема хрупкого базового класса) все преимущества декларативности и DSL немедленно вытекают из преимуществ этих структур данных (таблиц и наборов). Еще один плюс - вы можете изменить реализацию декларативного языка vm, если DSL более или менее абстрактен (хорошо спроектирован). сделать параллельную реализацию, например. или перенести его на другой ОС и т. д. все хорошо определенные модульные изолирующие интерфейсы или протоколы дают вам такую ​​свободу и простоту поддержки.

Минусы: ты угадаешь правильно. реализация универсального (и параметризованного DSL) императивного алгоритма / виртуальной машины может быть медленнее и / или потреблять больше памяти, чем конкретная. в некоторых случаях. если такие случаи редки - просто забудь об этом, пусть будет медленно. если это часто встречается - вы всегда можете расширить DSL/vm для этого случая. где-то тормозит все остальные случаи, конечно...

PS Frameworks находится на полпути между DSL и императивом. и как все промежуточные решения... они сочетают в себе недостатки, а не выгоды. они не такие безопасные и не такие быстрые:) посмотрите на хаскель "мастер на все руки" - он на полпути между сильным простым ML и гибким метапрограммой Пролог и... каким монстром он является. Вы можете смотреть на Пролог как на Haskell с булевыми функциями / предикатами. и насколько просто его гибкость против Haskell...

Мне просто интересно, почему никто не упомянул классы атрибутов как инструмент декларативного программирования на C#. Популярный ответ на этой странице только что говорил о LINQ как инструменте декларативного программирования.

Согласно Википедии

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

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

Просто чтобы добавить еще один пример с точки зрения разработки мобильных приложений. В iOS и Android у нас есть Interface Builders, где мы можем определить интерфейс приложений.

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

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

Кроме того, некоторые новые языки, такие как Angular JS, фокусируются на декларативном проектировании пользовательских интерфейсов, и мы можем увидеть множество других языков, предлагающих такую ​​же поддержку. Например, у JAVA нет хорошего декларативного способа рисовать нативные настольные приложения в JAVA Swing или JAVA FX, но в ближайшем будущем они могут.

Вы просили пример на C#, который является крайне «императивным» языком. Императив и декларативность находятся на двух концах спектра «что» и «как», и они часто смешиваются. Что касается декларативности, рассмотрите чистый HTML или CSS (без скриптов). HTML-документ, напримервообще не содержит императивных команд; в данном случае он просто объявляет, «каким» должен быть результат. В качестве императивного конца рассмотрим оператор C, например. Это чисто «императивный» вариант, сформированный в виде списка команд, сообщающих компьютеру, «как» выполнить работу.

Рассмотрим оператор SQL, например. Это находится где-то посередине. Он имеет декларативный аспект в предложениях FROM и WHERE, описывающий, «каким» должен быть результат. Но он явно структурирован как императивный оператор, начинающийся с команды SELECT.

Если вы зададите вопрос в контексте крайне императивного языка программирования, вы обычно получите пример «функционального» программирования, в котором некоторые базовые императивные операции упакованы так, что их можно использовать в более декларативном стиле. Обычным примером является функция цикла for, используемая для выполнения общих операций с массивом или объектом. Вы получаете что-то вродеПо сути, это императивный оператор, инструктирующий компьютер создать переменную и присвоить ей значение, но он вызывает функцию «где», которая придает ему декларативный вид. Он включает усеченный вызов функции, но механика цикла for заменена на «где». Его следует поместить ближе к императивному концу шкалы, чем пример SQL, но в контексте императивного языка он все еще остается относительно декларативным. Именно поэтому трудно получить однозначный ответ.

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

Императивное программирование - инструкции машинного языка, выполняемые ЦП

Декларативное программирование - SQL (язык структурированных запросов), выполняемый движком Spark в Delta Lake

Я думаю, что эта концепция часто слишком сложна.

Декларативное программирование = вызов функции

Императивное программирование = определение функции

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

Взгляните на ответ с самым высоким рейтингом:

      // Declarative: You call Where()
var results = collection.Where(num => num % 2 != 0); 

// Imperative: You implement Where()
List<int> results = new List<int>(); 
    foreach(var num in collection) { 
        if (num % 2 != 0)
            results.Add(num);
}

Или другой:

      var numbers = [1,2,3,4,5]
var doubled = []

// Imperative: You implement map()
for(var i = 0; i < numbers.length; i++) {
  var newNumber = numbers[i] * 2
  doubled.push(newNumber)
}
console.log(doubled) //=> [2,4,6,8,10]
      var numbers = [1,2,3,4,5]

// Declarative: You call map()
var doubled = numbers.map(function(n) {
  return n * 2
})
console.log(doubled) //=> [2,4,6,8,10]
      var numbers = [1,2,3,4,5]
var total = 0

// Imperative: You implement reduce()
for(var i = 0; i < numbers.length; i++) {
  total += numbers[i]
}
console.log(total) //=> 15
      var numbers = [1,2,3,4,5]

// Declarative: You call reduce()
var total = numbers.reduce(function(sum, n) {
  return sum + n
});
console.log(total) //=> 15

Если вы хотите углубиться, есть спектр:

  • Чем больше предопределенных функций вы используете, тем более «декларативным» он является.
  • Чем меньше функций вы используете, тем более «императивным» это становится.

Возьмем еще один приведенный пример:

      // Least declarative: Mostly implemented
const bestProducts = [];
for(let i = 0; i < products.length; i++) {
    let product = products[i];
    if (product.rating >= 5 && product.price < 100) {
        bestProducts.push(product);
    }
}

// More declarative: Function called, less implementation
const bestProducts = products.filter(function(product) {
    return product.rating >= 5 && product.price < 100;
});

// Most declarative: Function called, no implementation
const bestProducts = getBestProducts();
Другие вопросы по тегам