The Two Meanings of Declarative

For about the seventh time, now, I’ve been “corrected” on something in a way that isn’t really correct. The issue here is what is meant by a declarative language. Haskell and SQL are both called declarative. There are, though, very different senses in which these languages might qualify as declarative.

Haskell is a declarative language in that the program can be treated as a statement of facts, rather than as a set of commands that are sequenced in time. These facts, though, are about all sorts of things. They express the structure of the problem, but also the algorithms used to solve the problem, the intermediate data structures used between steps, and so on. I can implement merge sort, quick sort, and bubble sort in Haskell; and I can tell the difference.

SQL is a declarative language in that it’s a formal way for me to say what I want. The database decides how to find it. It’s true that there are some limitations: some databases perform far better with joins than with correlated IN clauses, for example. By and large, though, these are warts. I can’t describe most algorithms in SQL. It would be meaningless to try to identify whether an ORDER BY clause does a merge sort or bubble sort. The basic algorithms used by the system can depend on the definition of the table, the existence of indices, and even statistics gathered by the DBMS over time. You can bet your bottom dollar those algorithms aren’t themselves written in SQL (or even in PL/SQL or some other procedural extension).

These are, in other words, two different definitions of “declarative.” One language allows you to declare things about the computation. The other restricts you to declaring things about the problem. Critics and armchair observers would be well-advised to determine which is meant before blurting out “that doesn’t make sense, because Haskell is a declarative language.”

4 Comments

Haskell and SQL are similar languages in that their execution produces no side-effects — there’s no way to programmatically alter memory or program state (Haskell nomads being the intentional exception). I think that’s the meaning of declarative that you’re seeking. Some people refer to this as “functional” programming, but that’s not quite correct, as many languages have first-class functions but also rely on side-effects.

Your knowledge of SQL seems to be limited to one-liners. Most versions of SQL support things like variables and functions, the like of which you won’t see in a declarative language. SQL is generally thought as primarily a set based langauge with procedural capabilities.

A declarative language would be something like XSLT, ASP.NET markup, HTML, or XAML. In these langauges the code closely resembles the results. Things like order of execution are hard to determine, but that usually doesn’t matter much. Take XSLT for instance. It rarely matters if the transformation starts from the first XML element or the last, you will get the same result.

Now compare that to a sequence of SQL statements. If one performs an update before a select they will get a very different result than if the select comes first.