On many articles, describing the benefits of functional programming, I have seen functional programming languages, such as Haskell, ML, Scala or Clojure, referred to as "declarative languages" distinct from imperative languages such as C/C++/C#/Java. My question is what makes functional programming languages declarative as opposed to imperative.
An often encountered explanation describing the differences between Declarative and Imperative programming is that in Imperative programming you tell the computer "How to do something" as opposed to "What to do" in declarative languages. The problem I have with this explanation is that you are constantly doing both in all programming languages. Even if you go down to the lowest level assembly you are still telling the computer "What to do", you tell the CPU to add two numbers, you don't instruct it on how to perform the addition. If we go to the other end of the spectrum, a high level pure functional language like Haskell, you are in fact telling the computer how to achieve a specific task, that is what your program is a sequence of instructions to achieve a specific task which the computer does not know how to achieve alone. I understand that languages such as Haskell, Clojure, etc. are obviously higher level than C/C++/C#/Java and offer features such as lazy evaluation, immutable data structures, anonymous functions, currying, persistent data structures, etc. all which make functional programming possible and efficient, but I wouldn't classify them as declarative languages.
I've been playing around with Prolog recently and to me, Prolog is the closest programming language to a fully declarative language (At least in my opinion), if it is not the only fully declarative programming language. To elaborate programming in Prolog is done by making declarations which state either a fact (a predicate function which returns true for a specific input) or a rule (a predicate function which returns true for a given condition/pattern based on the inputs), rules are defined using a pattern matching technique. To do anything in prolog you query the knowledge base by substituting one or more of the inputs of a predicate with a variable and prolog tries to find values for the variable(s) for which the predicate succeeds.
My point is in prolog there are no imperative instructions, you basically telling (declaring) the computer what it knows and then asking (querying) about about the knowledge. In functional programming languages you are still giving instructions i.e. take a value, call function X and add 1 to it, etc, even if you are not directly manipulating memory locations or writing out computation step by step. I wouldn't say that programming in Haskell, ML, Scala or Clojure is declarative in this sense, though I may be wrong. Is proper, true, pure functional programming declarative in the sense that I described above.