Во многих статьях, описывающих преимущества функционального программирования, я видел функциональные языки программирования, такие как Haskell, ML, Scala или Clojure, называемые «декларативными языками», отличными от императивных языков, таких как C / C ++ / C # / Java. Мой вопрос заключается в том, что делает функциональные языки программирования декларативными, а не императивными.
Часто встречающееся объяснение, описывающее различия между декларативным и императивным программированием, состоит в том, что в императивном программировании вы говорите компьютеру «Как сделать что-то», а не «Что делать» в декларативных языках. Проблема с этим объяснением состоит в том, что вы постоянно делаете оба на всех языках программирования. Даже если вы переходите к сборке самого низкого уровня, вы все еще говорите компьютеру «Что делать», вы указываете ЦПУ добавить два числа, но не указываете, как выполнить сложение. Если мы перейдем к другому концу спектра, высокоуровневому чисто функциональному языку, такому как Haskell, вы на самом деле говорите компьютеру, как выполнить конкретную задачу, это то, что ваша программа представляет собой последовательность инструкций для достижения конкретной задачи, которую компьютер не знает, как выполнить в одиночку. Я понимаю, что такие языки, как Haskell, Clojure и т. Д., Очевидно, имеют более высокий уровень, чем C / C ++ / C # / Java, и предлагают такие функции, как отложенная оценка, неизменные структуры данных, анонимные функции, каррирование, постоянные структуры данных и т. Д. функциональное программирование возможно и эффективно, но я бы не классифицировал их как декларативные языки.
Для меня чисто декларативными языками был бы тот, который полностью состоит только из объявлений, примером таких языков может быть CSS (да, я знаю, что CSS технически не будет языком программирования). CSS просто содержит объявления стилей, которые используются HTML и Javascript страницы. CSS не может ничего делать, кроме как делать объявления, он не может создавать функции класса, то есть функции, которые определяют стиль отображения на основе некоторого параметра, вы не можете выполнять скрипты CSS и т. Д. Это для меня описывает декларативный язык (обратите внимание, я не сказал декларативный язык программирования ).
Обновить:
Я недавно играл с Прологом, и для меня Пролог - самый близкий язык программирования к полностью декларативному языку (по крайней мере, на мой взгляд), если это не единственный полностью декларативный язык программирования. Чтобы разработать программирование в Прологе, нужно сделать декларации, в которых указывается либо факт (функция предиката, которая возвращает истину для определенного ввода), либо правило (функция предиката, которая возвращает истину для данного условия / шаблона на основе входных данных), правила определяются с помощью метода сопоставления с образцом. Чтобы сделать что-либо в прологе, вы запрашиваете базу знаний, заменяя один или несколько входных данных предиката переменной, и пролог пытается найти значения для переменной (ей), для которой прецедент завершается успешно.
Суть в том, что в прологе нет обязательных инструкций: вы в основном рассказываете (объявляете) компьютеру, что он знает, а затем спрашиваете (спрашиваете) о знаниях. В функциональных языках программирования вы все еще даете инструкции, то есть берете значение, вызываете функцию X и добавляете к ней 1 и т. Д., Даже если вы не управляете непосредственно ячейками памяти или не записываете вычисления шаг за шагом. Я бы не сказал, что программирование на Haskell, ML, Scala или Clojure декларативно в этом смысле, хотя я могу ошибаться. Является ли правильное, истинное, чисто функциональное программирование декларативным в том смысле, что я описал выше.
(let [x 1] (let [x (+ x 2)] (let [x (* x x)] x)))
(надеюсь, вы поняли это, Clojure). Мой оригинальный вопрос: что отличает это от этого? x = 1; x += 2; x *= x; return x;
На мой взгляд, это в основном то же самое.