Monday, June 15, 2009

The elusive goal of non-procedural

From time to time, people mention the word "non-procedural". Usually, they are pushing some new technology, some new language or framework, some new thing for developers. The argument is: "In a procedural language, the developer must specify *how* to perform a task; in a non-procedural language, the developer simply specifies *what* must be done."

The implication is that non-procedural languages are more effective for the customer (that is, the customer that the pusher of said technology wants to add to their list). By merely specifying what instead of how, programs can be written faster and with greater reliability.

I have no argument with technology that allows us to write programs faster and more reliably. I myself find that I am faster with C++ than C, and faster with C# than C++, and yet faster with Perl than with C#.

It is the term "non-procedural" that bothers me.

I will argue that third-generation languages (such as the venerable FORTRAN and COBOL) are non-procedural.

"What?!?" you exclaim, "Those old languages are clearly procedural. We have to specify the steps for everything!"

Strictly speaking, that is not true. It is only in assembly language that one must specify the steps for everything. Once you move to a third-level language, the work of register allocation and some data conversion are handled by the compiler. You specify lots of things, but not everything.

So in terms register assignments, compared to assembly language, FORTRAN and COBOL are non-procedural. (You specify *what* not *how*.)

SQL, compared to FORTRAN and COBOL, is non-procedural, in that it handles the input-output operations, comparisons, and sorting.

The issue is not a binary "procedural" or "non-procedural" one. It is a gradient.

Different languages provide different levels of abstraction. SQL provides a (relatively) high level, FORTRAN and COBOL (and C# and Java) an intermediate level, and assembly language a low level. The higher the abstraction, the easier the task.

I predict that at some point in the future we will have a new model for programming databases, one at a higher level than SQL. (Let's call it "uber SQL", just for grins.) The proponents will advertise the ease at which tasks can be accomplished. They will also point to the (then-perceived) flaws with SQL: having to specify how tables are related, and the detailed queries that tell the DBMS how to perform the operation. UberSQL will be considered non-procedural, and SQL will be derided as "too procedural, even for a non-procedural language".

And that is my point. It's not about "procedural" or "non-procedural". It's about abstraction. The higher the abstraction, the more effecient the development. (Because you have to think about less.)

So think in terms of level of abstraction. Avoid the "non-procedural trap", a one-time, "we've done it", error on the way to better programming. We're still developing languages, we're still developing levels of abstractions, and we're still learning how to think.

* * * * *

P.S. Particularly alert readers may take exception with my statement that "only in assembly language that one must specify everything" and suggest machine code as the bottom layer. Other readers may vault past machine code and suggest microcode. I accede to both. I used assembly language to provide a lower level of abstraction. I think the argument against the term "non-procedural" holds, wherever we define the bottom. (Or even if we agree to turtles, all the way down.)

No comments: