What Makes Functional Programming Languages Declarative?

declarative-programmingfunctional programmingimperative-programmingprolog

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.

A pure declarative languages for me would be one which is comprised entirely of declarations only, an example of such a languages would be CSS (Yes I know CSS would technically not be a programming language). CSS just contains style declarations which are used by the HTML and Javascript of the page. CSS cannot do anything else besides make declarations, it cannot create class functions, i.e. functions which determine the style to display based on some parameter, you cannot execute CSS scripts, etc. That for me describes a declarative language (notice I did not say declarative programming language).

Update:

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.

Best Answer

You seem to be drawing a line between declaring things and instructing a machine. There is no such hard-and-fast separation. Because the machine that's being instructed in imperative programming need not be physical hardware, there is much freedom for interpretation. Almost everything can be seen as an explicit program for the right abstract machine. For example, you could see CSS as a rather high level language for programming a machine that primarily resolves selectors and sets attributes of the thus-selected DOM objects.

The question is whether such a perspective is sensible, and conversely, how closely the sequence of instructions resembles a declaration of the result being computed. For CSS, the declarative perspective is clearly more useful. For C, the imperative perspective is clearly predominant. As for languages as Haskell, well…

The language has specified, concrete semantics. That is, of course one can interpret the program as a chain of operations. It doesn't even take too much effort to choose the primitive operations so that they map nicely onto commodity hardware (this is what the STG machine and other models do).

However, the way Haskell programs are written, they frequently can sensibly be read as a description of the result to be computed. Take, for example, the program to compute the sum of the first N factorials:

sum_of_fac n = sum [product [1..i] | i <- ..n]

You can desugar this and read it as a sequence of STG operations, but far more natural is to read it as a description of the result (which is, I think, a more useful definition of declarative programming than “what to compute”): The result is the sum the products of [1..i] for all i = 0, …, n. And that is far more declarative than almost any C program or function.

Related Topic