Що таке декларативне програмування? [зачинено]


193

Я продовжую чути, як цей термін кидався в декількох різних контекстах. Що це?


7
Відповідь, яку ви вибрали як правильну (вказана зеленою галочкою), невірна. Він не визначає, чим відрізняється декларативне програмування від його антитези - імперативного програмування. Подумайте про зміну вибору.
Шелбі Мур III

3
Так, відповідь, позначена правильною, НЕ є правильною.
Дермот

4
@ShelbyMooreIII Також вкажіть, яка відповідь правильна, щоб ми могли її прочитати!
vivek.m

@ vivek.m Я сьогодні дав нову відповідь .
Шелбі Мур III

Відповіді:


148

Декларативне програмування - це коли ви пишете свій код таким чином, щоб він описував, що ви хочете зробити, а не як ви хочете це зробити. Компілятор залишається вирішити, як це зробити.

Прикладами декларативних мов програмування є SQL та Prolog.


29
Ви все ще повинні з'ясувати "як" сказати комп'ютеру "чого" ви хочете :)
hasen

7
@hasenj цей та інші відповіді не визначають єдиний атрибут, не поділений з імперативним програмуванням, - це незмінність .
Шелбі Мур III

3
Це буде дуже здорово, якщо ви можете згадати про те, чим він відрізняється від імперативного програмування (такі мови, як C, C ++, C #), тоді читачам буде легше розібратися в різниці.
RBT

1
програміст : "Я хочу подорожувати до Парижа". декларативне (с) : "Як би ви хотіли туди потрапити? плисти на човні? чи літати на літаку? Можливо, проплисти на півдорозі, а потім пролетіти рештою дороги туди?" програміст : "Мені не цікаво, як це робиться". імператив (sql) : "Не хвилюйтесь. Я можу запитати, що вам потрібно". ( саме так я розумію відповідь )
нат

Як SQL може бути декларативним, якщо він підтримує вирази, які не є прозорими?
java-addict301

80

Інші відповіді вже роблять фантастичну роботу, пояснюючи, що таке декларативне програмування, тому я просто надам кілька прикладів, чому це може бути корисним.

Контекстна незалежність

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

Візьмемо yaccяк приклад. Це генератор аналізатора. компілятор компілятора, зовнішній декларативний DSL для опису граматики мови, щоб парсер для цієї мови міг автоматично генеруватися з опису. Через її контекстну незалежність ви можете робити багато різних речей з такою граматикою:

  • Створіть аналізатор С для цієї граматики (оригінальний випадок використання для yacc)
  • Створіть аналізатор C ++ для цієї граматики
  • Створіть Java-аналізатор для цієї граматики (використовуючи Jay)
  • Створіть аналізатор C # для цієї граматики (використовуючи GPPG)
  • Створіть аналізатор Ruby для цієї граматики (використовуючи Racc)
  • Створіть візуалізацію дерева для цієї граматики (використовуючи GraphViz)
  • просто зробіть певне, вигадливе форматування та виділення синтаксису самого вихідного файлу yacc та включіть його до свого Довідкового посібника як синтаксичну специфікацію вашої мови

І багато іншого …

Оптимізація

Оскільки ви не призначаєте комп’ютеру, які кроки робити та в якому порядку, він може переставити програму набагато вільніше, можливо, навіть виконувати деякі завдання паралельно. Хороший приклад - планувальник запитів та оптимізатор запитів для бази даних SQL. Більшість баз даних SQL дозволяють відображати запит, який вони насправді виконують, порівняно з запитом, який ви попросили їх виконати. Часто ці запити нічого не виглядаютьяк один одного. Планувальник запитів враховує те, про що ви навіть і не мріяли: затримка обертання диска, наприклад, або те, що якась абсолютно інша програма для зовсім іншого користувача просто виконала подібний запит та таблицю, яку ви є. приєднавшись до того, що ви так наполегливо працювали, щоб уникнути завантаження, так чи інакше вже в пам'яті.

Тут є цікавий компроміс: машині доводиться більше працювати, щоб зрозуміти, як зробити щось необхідним мовою, але коли вона це зрозуміє, у неї набагато більше свободи та набагато більше інформації для оптимізації. етап.


23

Вільно:

Декларативне програмування має на меті:

  • Набори декларацій або декларативних висловлювань, кожне з яких має значення (часто в проблемній області) і їх можна розуміти незалежно та ізольовано.

Імперативне програмування має тенденцію до: -

  • Послідовності команд, кожна з яких виконує якусь дію; але який може мати або не мати значення в проблемній області.

Як результат, імперативний стиль допомагає читачеві зрозуміти механіку того, що система насправді робить, але може дати мало розуміння проблеми, яку вона має намір вирішити. З іншого боку, декларативний стиль допомагає читачеві зрозуміти проблематичну область та підхід, який система застосовує до вирішення проблеми, але є менш інформативним щодо питання механіки.

Реальні програми (навіть ті, написані мовами, що сприяють кінцям спектру, наприклад, ProLog або C), як правило, обидва стилі представлені в різній мірі в різних точках, щоб задовольнити різні складності та комунікаційні потреби твору. Один стиль не перевершує інший; вони просто служать різним цілям, і, як у багатьох речах у житті, помірність є ключовою.


Це правильна відповідь. Не що-небудь із того бурмотіння вище
Кшиштоф Венде

Дякую за те, що ви не тільки відповідали на питання, але робили це "Поясніть, як мені 5" із контекстом та практичністю. Відмінна відповідь.
Монсто

17

Ось приклад.

У CSS (використовується для стилювання HTML-сторінок), якщо ви хочете, щоб елемент зображення був високим 100 пікселів і шириною 100 пікселів, ви просто "заявляєте", що це те, що ви хочете наступним чином:

#myImageId {
height: 100px;
width: 100px;
}

Ви можете вважати CSS мовою декларативного стилю.

Двигун браузера, який читає та інтерпретує цей CSS, може зробити зображення таким високим і таким широким, як тільки воно не хоче. Різні браузери (наприклад, двигун для IE, двигун для Chrome) реалізують це завдання по-різному.

Їх унікальна реалізація, звичайно, НЕ написана декларативною мовою, а такою процедурною, як Assembly, C, C ++, Java, JavaScript або Python. Цей код є купою кроків, які слід виконувати поетапно (і може включати виклики функцій). Це може робити такі речі, як інтерполяція значень пікселів і відображення на екрані.


11

Мені шкода, але я маю згоду з багатьма іншими відповідями. Я хотів би припинити це заплутане нерозуміння визначення декларативного програмування.

Визначення

Референтна прозорість (RT) суб-виразів є єдиним необхідним атрибутом декларативного вираження програмування , оскільки це єдиний атрибут, який не поділяється на імперативне програмування.

Інші цитовані атрибути декларативного програмування походять від цієї RT. Будь ласка, натисніть гіперпосилання вище для детального пояснення.

Приклад електронних таблиць

У двох відповідях згадується програмування електронних таблиць. У випадках, коли програмування електронних таблиць (так само формули) не має доступу до змінного глобального стану, тоді це декларативне програмування. Це тому , що змінні значення осередків є монолітним введенням і виведенням з main()(всієї програми). Нові значення не записуються в осередки після виконання кожної формули, тому вони не змінюються протягом декларативної програми (виконання всіх формул у таблиці). Таким чином, відносно один одного формули розглядають ці змінні клітини як незмінні. Функція RT дозволена для доступу до незмінного глобального стану (а також локального стану, що змінюється ).

Таким чином, можливість мутувати значення в осередках, коли програма закінчується (як вихід з main()), не робить їх змінними збереженими значеннями в контексті правил. Ключове відмінність полягає в тому, що значення комірок не оновлюються після виконання кожної формули електронної таблиці, тому порядок виконання формул не має значення. Значення комірок оновлюються після виконання всіх декларативних формул.


1
Непередбачені побічні ефекти можуть зруйнувати зв’язок між заявленим та фактичною поведінкою програми. Я пояснив це детальніше в новій відповіді .
Шелбі Мур ІІІ

8

Декларативне програмування - це малюнок, де імперативне програмування - це інструкція щодо малювання цієї картини.

Ви пишете в декларативному стилі, якщо ви "Розповідаєте, що це таке", а не описуєте кроки, які повинен здійснити комп'ютер, щоб дістатися туди, де ви хочете.

Коли ви використовуєте XML для розмітки даних, ви використовуєте декларативне програмування, оскільки ви говорите: "Це людина, день народження, і там є адреса вулиці".

Деякі приклади, де декларативне та імперативне програмування поєднуються для отримання більшого ефекту:

  • Фонд презентацій Windows використовує декларативний синтаксис XML, щоб описати, як виглядає користувальницький інтерфейс, і як взаємозв'язки (прив’язки) між елементами управління та основними структурами даних.

  • Структуровані файли конфігурації використовують декларативний синтаксис (простий як пари "ключ = значення") для визначення того, що означає рядок або значення даних.

  • HTML позначає текст тегами, які описують, яку роль має кожен фрагмент тексту стосовно всього документа.


2
Хоча XML є декларативним, я б не пішов так далеко, щоб сказати, що це декларативне програмування просто тому, що немає активної семантики, пов'язаної з розміткою. Скажіть, що щось є адресою, не допомагає з’ясувати, що ви хочете з цим зробити.
ГенріР

1
Має бути базовий контекст (домен?), В якому використовується декларативна програма. Тож використання XML у поєднанні з ANT може розглядатися як декларативна програма.
Gutzofter

7

Декларативне програмування - це програмування з деклараціями, тобто декларативними реченнями. Декларативні речення мають ряд властивостей, що відрізняють їх від імперативних речень. Зокрема, декларації:

  • комутативний (може бути упорядкований)
  • асоціативний (можна перегрупувати)
  • ідентичний (може повторюватися без зміни значення)
  • монотонні (декларації не віднімають інформацію)

Важливим моментом є те, що всі ці структурні властивості є предметом ортогональних. Декларативне не про "Що проти як" . Ми можемо оголосити (представляти і обмежити) "як" так само легко, як і оголосити "що" . Декларативне - це структура, а не зміст.Декларативне програмування має суттєвий вплив на те, як ми абстрагуємо і рефакторируем свій код, і як ми модулюємо його в підпрограмах, але не стільки на доменну модель.

Часто ми можемо перетворити від імперативного до декларативного, додавши контекст. Наприклад, "Поверніть ліворуч. (... дочекайтеся ...) Поверніть праворуч." до "Боб поверне ліворуч на перехресті Фу та Бару о 11:01. Боб поверне праворуч на перехресті Бару та База о 11:06". Зауважте, що в останньому випадку пропозиції є безвідмовними та комунікативними, тоді як у першому випадку перестановка чи повторення пропозицій суттєво змінить зміст програми.

Щодо монотонних , декларації можуть додавати обмеження, які віднімають можливості . Але обмеження все ж додають інформацію (точніше, обмеження - це інформація). Якщо нам потрібні декларації, що залежать від часу, типово моделювати це з чітко вираженою часовою семантикою - наприклад, від "куля плоска" до "куля плоска в момент T". Якщо ми маємо дві суперечливі декларації, ми маємо непослідовну декларативну систему, хоча це може бути вирішено шляхом введення м'яких обмежень (пріоритетів, ймовірностей тощо) або використання параконсистентної логіки.


1
Декларативні вирази сприяють передбачуваній поведінці програми, імперативні можуть сприяти задуманому чи ненавмисному. Декларативне не повинно бути комутативним та безвідмовним, якщо це навмисна семантика.
Шелбі Мур III,

6

Описуючи на комп’ютері те, що ти хочеш, а не як щось робити.


6

уявіть собі сторінку Excel. За допомогою стовпців, заповнених формулами для обчислення податкової декларації.

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

Це щось таке, про що йдеться в декларативному програмуванні. Ви оголошуєте простір проблеми та рішення, а не потік програми.

Prolog - єдина декларативна мова, якою я користуюся. Це вимагає іншого типу мислення, але добре навчитися, якщо просто піддавати вас чомусь іншому, ніж типову процедурну мову програмування.


6

Я вдосконалив своє розуміння декларативного програмування з грудня 2011 року, коли я дав відповідь на це питання. Тут випливає моє сучасне розуміння.

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

Імперативне програмування зберігається та читається зміненому стані, тому впорядкування та / або дублювання інструкцій програми можуть змінити поведінку (семантику) програми (і навіть спричинити помилку, тобто ненавмисну ​​поведінку).

У самому наївному та крайньому сенсі (що я стверджував у своїй попередній відповіді) декларативне програмування (DP) уникає всіх збережених змінних станів, таким чином впорядкування та / або дублювання інструкцій програми НЕ можуть змінювати поведінку (семантику) програми .

Однак таке екстремальне визначення було б не дуже корисним у реальному світі, оскільки майже кожна програма передбачає збережений стан, що змінюється. Приклад електронної таблиці відповідає цьому крайньому визначенню DP, оскільки весь програмний код запускається до завершення однією статичною копією стану введення, перш ніж нові стани будуть збережені. Потім, якщо будь-який стан змінено, це повторюється. Але більшість реальних програм не може обмежуватися такою монолітною моделлю змін у державі.

Більш корисним визначенням DP є те, що впорядкування та / або дублювання інструкцій програмування не змінюють жодної непрозорої семантики. Іншими словами, не відбувається прихованих випадкових змін у семантиці - будь-які зміни в порядку розпорядження програми та / або дублювання викликають лише намічені та прозорі зміни в поведінці програми.

Наступним кроком було б поговорити про те, які моделі програмування чи парадигми допомагають в DP, але тут не в цьому питання.


Оновлення: зверніться також до більш вичерпного пояснення в іншій моїй відповіді щодо визначення декларативного програмування.
Шелбі Мур III,

Functional programmingце гучне слово в наші дні, яке по суті є підмножиною декларативного програмування. LINQ у мові C # є елементом функціонального програмування, коли сама мова є імперативною від природи. Таким чином, C # стає свого роду гібридом, що йде за цим визначенням.
RBT

1
Посилання compute.com мертве.
Кедар Массваде

5

Це метод програмування, заснований на описі того, що щось має робити чи бути замість того, щоб описувати, як це має працювати.

Іншими словами, ви не пишете алгоритми, складені з виразів, ви просто компонуєте, як ви хочете, щоб все було. Два хороших приклади - HTML та WPF.

Ця стаття у Вікіпедії - це хороший огляд: http://en.wikipedia.org/wiki/Declarative_programming


1
Незначна каламбур. WPF - це бібліотека, насправді не мова чи парадигма. Я думаю, ви справді хотіли сказати, що XAML є прикладом декларативної мови.
Нік

І як би ви описали програмування за допомогою бібліотеки / фреймворку?
Gutzofter

Неправильно стверджувати, що декларативне програмування не може містити вирази. Ключова відмінність - вирази не можуть мутувати збережені значення .
Шелбі Мур III

HTML не є мовою програмування
lud

5

Оскільки я написав попередню відповідь, я сформулював нове визначення декларативного властивості, яке цитується нижче. Я також визначив імперативне програмування як подвійне властивість.

Це визначення перевершує те, що я надав у своїй попередній відповіді, оскільки воно є лаконічним і воно більш загальне. Але це може бути складніше, тому що наслідки теорем про незавершеність, застосовних до програмування та життя в цілому, люди важко загорнути.

Цитується пояснення визначення обговорює роль чистого функціонального програмування в декларативному програмуванні.

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

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

Занадто спрощене, технічно неточне і часто неоднозначне декларативне визначення як " що робити ", а імператив як " як робити " . Неоднозначний випадок - " що " - це " як " у програмі, яка виводить програму - компіляторі.

Очевидно, що безмежна рекурсія, яка робить мову Тьюрінга завершеною , є аналогічно і в семантиці - не тільки в синтаксичній структурі оцінки (він же оперативної семантики). Це логічно приклад, аналогічний теоремі Геделя - " будь-яка повна система аксіом також невідповідна ". Поміркуйте над суперечливою дивністю цієї цитати! Це також приклад, який демонструє, як вираз семантики не має доказуваної межі, тому ми не можемо довести 2, що програма (і аналогічно її семантика) зупиняє також теорему Холтінга.

Теореми про незавершеність випливають із фундаментальної природи нашого Всесвіту, яка, як сказано у Другому законі термодинаміки, « є ентропією (інакше числом незалежних можливостей) навіки має тенденцію до максимуму ». Кодування та розробка програми ніколи не закінчуються - вона жива! - тому що вона намагається вирішити справжню потребу в світі, а семантика реального світу завжди змінюється і має тенденцію до більше можливостей. Люди ніколи не перестають відкривати нові речі (включаючи помилки в програмах ;-).

Щоб точно і технічно зафіксувати це вищезазначене бажане поняття всередині цього дивного всесвіту, який не має краю (подумайте про те, що немає "поза" нашої Всесвіту), потрібно чітке, але оманливо-не просте визначення, яке буде звучати неправильно, поки не буде пояснено глибоко.

Визначення:


Декларативне властивість є там, де може існувати лише один можливий набір висловлювань, який може виражати кожну конкретну модульну семантику.

Властивість імперативу 3 - це подвійна, де семантика суперечлива за складом та / або може бути виражена варіаціями наборів тверджень.


Це визначення декларативного є виразно локальним за семантичним розмахом, тобто означає, що воно вимагає, щоб модульний семантичний зберігав своє послідовне значення незалежно від того, де і як воно є інстанційним та використаним у глобальному масштабі. Таким чином, кожен декларативно-модульний семантичний має бути внутрішньо ортогональним для всіх можливих інших - і не є неможливим (через теореми про незавершеність) глобальним алгоритмом чи моделлю для засвідчення послідовності, що також є пунктом " Більше не завжди краще " Роберта Харпера, професора комп'ютерних наук в університеті Карнегі Меллон, один з дизайнерів Standard ML.

Приклади цих модульних декларативною семантики включають категорії теорії функтори , наприклад , вApplicative , номінальний введення, просторів імен, названих полів і WRT на операційному рівні семантики то чисто функціонального програмування.

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

Прикладом вищезгаданого визначення є набір формул у клітинках програми електронних таблиць - які, як очікується, не дадуть однакового значення при переміщенні до різних комірок стовпців та рядків, тобто змінених ідентифікаторів комірок. Ідентифікатори комірок є частиною і не є зайвою для передбачуваного значення. Таким чином, кожен результат електронної таблиці є унікальним wrt для ідентифікаторів комірок у наборі формул. Послідовним модульним семантичним в даному випадку є використання ідентифікаторів комірок як введення та виведення чистих функцій для формул комірок (див. Нижче).

Hyper Text Markup Language aka HTML - мова для статичних веб-сторінок - є прикладом декларативної мови (але не зовсім 3 ), яка (принаймні до HTML 5) не мала можливості виражати динамічну поведінку. HTML - це чи не найпростіша мова для вивчення. Для динамічної поведінки загальнозміцнюючу мову сценаріїв, наприклад JavaScript, зазвичай поєднували з HTML. HTML без JavaScript відповідає деклараційному визначенню, оскільки кожен іменний тип (тобто теги) зберігає своє послідовне значення під складом у межах правил синтаксису.

Конкуруючим визначенням декларативного є комутативні та ідентифікуючі властивості семантичних висловлювань, тобто те, що висловлювання можна переупорядковувати та дублювати, не змінюючи значення. Наприклад, заяви, які присвоюють значення названим полям, можна переупорядкувати та дублювати, не змінюючи значення програми, якщо ці імена є модульними wrt у будь-якому загальному порядку. Імена іноді означають порядок, наприклад, ідентифікатори комірок включають їх стовпці та рядки - переміщення загальної кількості на електронній таблиці змінює її значення. В іншому випадку ці властивості неявно вимагають глобальнихпослідовність семантики. Взагалі неможливо розробити семантику висловлювань, щоб вони залишалися послідовними, якщо випадковим чином упорядковано чи дублюється, тому що порядок та дублювання є властивими семантиці. Наприклад, твердження "Foo існує" (або конструкція) і "Foo не існує" (і знищення). Якщо вважати випадкову невідповідність ендемічною для передбачуваної семантики, то приймається це визначення як достатньо загальне для декларативної властивості. По суті, це визначення є вакуумним як узагальнене визначення, оскільки воно намагається зробити послідовність ортогональною семантиці, тобто спростувати той факт, що Всесвіт семантики динамічно не обмежена і не може бути захоплена глобальною парадигмою узгодженості.

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

C, Java, C ++, C #, PHP та JavaScript не є особливо декларативними. Синтаксис Copute і синтаксис Python більш декларативно поєднані з наміченими результатами , тобто послідовною синтаксичною семантикою, яка усуває сторонні, так що можна легко зрозуміти код після його забуття. Копут і Хаскелл застосовують детермінізм оперативної семантики і заохочують " не повторювати себе " (DRY), оскільки вони дозволяють лише чисто функціональну парадигму.


2 Навіть там, де ми можемо довести семантику програми, наприклад, з мовою Coq, це обмежується семантикою, яка виражається під час набору тексту , і введення ніколи не може охопити всю семантику програми - навіть для мов, які є не Turing завершений, наприклад, за допомогою HTML + CSS можна висловити непослідовні комбінації, які, таким чином, мають не визначену семантику.

3 Багато пояснень помилково стверджують, що лише імперативне програмування має синтаксично впорядковані твердження. Я прояснив цю плутанину між імперативним та функціональним програмуванням . Наприклад, порядок висловлювань HTML не зменшує узгодженість їх значення.


Редагувати: Я опублікував такий коментар у блозі Роберта Харпера:

у функціональному програмуванні ... діапазон зміни змінної є типом

Залежно від того, як можна відрізнити функціональне від імперативного програмування, ваш "присвоєний" імперативній програмі також може мати тип, що обмежує його мінливість.

Єдине неясне визначення, яке я в даний час оцінюю для функціонального програмування, це: а) функції як першокласні об'єкти та типи; б) перевага для рекурсії через петлі та / або в) чисті функції - тобто ті функції, які не впливають на потрібну семантику програми при запам'ятовуванні ( таким чином, абсолютно чисто функціональне програмування не існує в денотаційній семантиці загального призначення через вплив оперативної семантики, наприклад, розподіл пам'яті ).

Властивість idempotent чистої функції означає, що виклик функції її змінних може бути заміщений її значенням, що, як правило, не стосується аргументів імперативної процедури. Чисті функції, здається, є декларативними в WTR для невпорядкованих переходів стану між типами вводу та результату.

Але склад чистих функцій не підтримує такої послідовності, тому що можна моделювати імперативний процес побічного (глобального стану) чистою функціональною мовою програмування, наприклад, IOMonad Haskell і, крім того, цілком неможливо запобігти виконанню таких в будь-яку повну чисту функціональну мову програмування.

Як я писав у 2012 році, що здається аналогічним консенсусом коментарів у вашому недавньому блозі , декларативне програмування - це спроба зафіксувати уявлення про те, що передбачувана семантика ніколи не є непрозорою. Прикладами непрозорої семантики є залежність від порядку, залежність від стирання семантики вищого рівня на шарі оперативної семантики (наприклад, касти не є перетвореннями, а перероблена генетика обмежує семантику вищого рівня ) та залежність від змінних значень, які неможливо перевірити (доведено правильно) мовою програмування.

Таким чином, я дійшов висновку, що декларативними можуть бути лише нетурюрські цілі мови.

Таким чином, однією однозначною і чіткою ознакою декларативної мови може бути те, що її результат може бути доведений, щоб він відповідав певній безлічі генеративних правил. Наприклад, для будь-якої конкретної програми HTML (ігнорування розбіжностей у способах розходження інтерпретаторів), які не написані сценаріями (тобто не є Тюрінг завершеним), то її вихідна змінність може бути безліч. Або, більш лаконічно, програма HTML - це чиста функція її змінності. Програма електронних таблиць - це чиста функція її вхідних змінних.

Тож мені здається, що декларативні мови є антитезою безмежної рекурсії , тобто за самореференційними теоремами про неповноту Гереда не можна довести.

Лесі Лампорт написала казку про те, як Евклід міг би працювати над теоремами про незавершеність Геделя, застосованими до доказів математики в контексті мови програмування, завдяки конгруенції між типами та логікою (листування Керрі-Говарда тощо).


4

Декларативне програмування - це "програмування на мовах, що відповідають ментальній моделі розробника, а не оперативній моделі машини".

Різниця між декларативним та імперативним програмуванням добре ілюструється проблемою розбору структурованих даних.

Імперативна програма використовувала б взаємно рекурсивні функції для споживання вхідних даних та генерування даних. Декларативна програма виражає граматику, яка визначає структуру даних, щоб потім їх можна було розібрати.

Різниця між цими двома підходами полягає в тому, що декларативна програма створює нову мову, більш узгоджену з ментальною моделлю проблеми, ніж її мова-хост.


2

Це може здатися дивним, але я б додав Excel (або будь-яку електронну таблицю дійсно) до списку декларативних систем. Хороший приклад цього наведено тут .


1

Я б пояснив це як DP - це спосіб висловити

  • Вираз мети , умови - то , що ми шукаємо. Є один, може, чи багато?
  • Деякі відомі факти
  • Правила, що розширюють факти знань

... і там, де існує відрахуваний двигун, який зазвичай працює з алгоритмом уніфікації для пошуку цілей.


-1

Наскільки я можу сказати, його почали використовувати для опису систем програмування, як Prolog, оскільки prolog (нібито) стосується декларування речей абстрактним чином.

Це все більше означає дуже мало, оскільки має визначення, яке дають користувачі вище. Повинно бути зрозуміло, що між декларативним програмуванням Haskell існує прогалина проти декларативного програмування HTML.


1
Не існує «прогалини між декларативним програмуванням Haskell, як проти декларативного програмування HTML», оскільки кореневим атрибутом декларативного програмування є незмінність збережених значень.
Шелбі Мур III

Як би там не було, існує велика різниця між специфічною для домену мовою, яка обмежена навіть її неявними обчисленнями, порівняно з повноцінною системою програмування.
Marcin

Домовились. Тюрінг-повнота є ортогональною незмінності збережених значень. Отже, ми не повинні пов'язувати атрибут декларативного проти імперативного. Дякуємо за роздуми за одним із атрибутів (Тюрінг-повнота), які можуть спричинити цю «затоку».
Шелбі Мур III

Повнота завершення вимагає лише необмеженої рекурсії . Незмінюваність збережених значень не виключає безмежної рекурсії. Таким чином вони є ортогональними атрибутами.
Шелбі Мур III

-2

Ще кілька прикладів декларативного програмування:

  • Розмітка ASP.Net для прив'язки даних. Наприклад, він просто говорить "заповнити цю сітку цим джерелом" і залишає її в системі для того, як це відбувається.
  • Виразки Linq

Декларативне програмування є приємним, тому що воно може допомогти спростити вашу ментальну модель * коду і тому, що воно може з часом бути масштабнішим.

Наприклад, скажімо, у вас є функція, яка робить щось із кожного елемента в масиві чи списку. Традиційний код виглядатиме так:

foreach (object item in MyList)
{
   DoSomething(item);
}

Ніякої великої справи там немає. Але що робити, якщо ви використовуєте синтаксис з більш декларативністю і замість цього визначаєте DoSomething () як дію? Тоді ви можете сказати це так:

MyList.ForEach(DoSometing);

Це, звичайно, більш стисло. Але я впевнений, що у вас є більше проблем, ніж просто зберегти два рядки коду тут і там. Продуктивність, наприклад. За старим способом обробку потрібно було робити послідовно. Що робити, якщо метод .ForEach () дозволив вам сигналізувати, що він може обробляти паралельно, автоматично, автоматично? Тепер раптом ви зробили свій код багатопоточним дуже безпечним способом і змінили лише один рядок коду. Насправді є розширення для .Net, яке дозволяє робити саме це.

  • Якщо ви перейдете за цим посиланням, вас переведе на публікацію в блозі мого друга. Весь пост трохи довгий, але ви можете прокрутити вниз до заголовка під назвою "Проблема" _ і забрати його там немає проблем. *


Деклараційне програмування може мутувати збережені значення ... це просто те, що ви вказуєте (оголошуєте) те, що хочете мутувати, замість того, як саме робити мутацію. Що ще ви вважаєте, що заявник sql INSERT або UPDATE у sql робить?
Joel Coehoorn

Ви пропускаєте те, що якщо ваші функції не є чистими, то випадкові побічні ефекти можуть зруйнувати взаємозв'язок між тим, що ви заявили, та фактичною поведінкою програми. Я пояснив це детальніше в новій відповіді .
Шелбі Мур ІІІ,

-3

Це залежить від того, як ви подаєте відповідь на текст. В цілому ви можете подивитися на програму з певного вигляду, але це залежить від того, під яким кутом ви дивитесь на проблему. Я розпочну з вас програму: Темний автобус, Автомобіль, Час, Висота Цілого типу

Знову ж таки, це залежить від загальної проблеми. Можливо, вам доведеться скоротити його через програму. Сподіваюся, що це допомагає та потребує зворотного зв’язку, якщо цього немає. Спасибі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.