Saturday, April 30, 2011

Speaking in tongues

In the 1960s, Gerald Weinberg wrote "The Psychology of Computer Programming", in which he observed that programs are not only written but read (by the author and other programmers). He also observed that programming languages are written but not spoken. No one ever "says something in Fortran".

It is an observation that was true at the time, yet I think we now have programming languages that can -- almost -- be considered a spoken language.

The early languages of FORTRAN and COBOL were meant to be written and read (silently). FORTRAN had the terse syntax that persists in most languages today; COBOL had a wordy syntax with the explicit purpose of readability. But no one intended for people to read COBOL out loud. It's wordiness was for the benefit of programming managers and interchangeable programmers.

FORTRAN offered a basic loop with the code:

DO

BASIC improved upon that syntax with:

FOR I = 1 TO 10

Notice that in BASIC, the label denoting the end of the iterating block has been removed. (BASIC uses a separate statement, NEXT, to mark the end of the block.)

C and C++ use the "for" loop:

for (int i = 0; i < 10; i++)

But all of these are in the realm of iterating a known number of times. BASIC, C, and C++ also have "while" loops, to iterate while a condition is true. But "for" loops and "while" loops still require a fair amount of thinking about the looping. A different notion of iterating is "for each of these things", and multiple languages have such constructs.

C++/STL introduced the concept of iterators to the language, and allowed for more concise (and consistent) notation for iterating over a set of objects. The STL provided more than a set of convenient classes -- it provided a set of common idioms for frequently-used constructs. These common idioms allow a person to translate the code

for (Object::const_iter iter(objects.begin()); iter != objects.end(); iter++)
{
iter->do_something()
}

into "for each member of the set of objects, do something". Yet this approach of common idioms still requires familiarity with the language and the work of translation from the C++ idiom to the English.

Microsoft has not ignored this trend. Visual Basic had (and C# has) the "foreach" keyword for iteration, and a recent update to the .NET Framework introduced the Enumerable.Range(start, count) iterator. The latter is a bit clumsy, but serviceable.

The Ruby language uses the method "each()" to iterate over a collection. This is eminently more readable than the C++/STL version: it requires no translation of idiom.

These constructs allow us to read the program -- out loud -- more easily and with less translation.

Speaking a program -- perhaps the proper verb is "orating" -- is important. Our brain's speech centers process information differently that the visual centers. When we orate, we think differently than when we read to ourselves. This different thought process helps us identify errors in our logic. (I suspect that this effect is at work when we explain a failing program to another programmer and during the explanation we understand the failure. I think it also is at work with the pair-programming concept of Extreme Programming and Agile Development, helping programmers identify errors early.)

I don't expect programming languages to be used for grand poetry (or even bad poetry) any time soon. But the concept of orating a program may be within reach.

No comments: