Thursday, 16 May 2013

The Rivers of Babylon

The Tao gave birth to machine language. Machine language gave birth to the assembler.
The assembler gave birth to the compiler. Now there are ten thousand languages.
Each language has its purpose, however humble. Each language expresses the Yin and Yang of software. 
Each language has its place within the Tao.
But do not program in COBOL if you can avoid it.



The universe of computer programming languages is in a constant state of evolution. Paradigms once considered vogue are exhausted and shelved, only for new paradigms to be embraced according to the latest schools of thought.

One of the questions I am mostly frequently asked, whether in interviews or in social situations where I am foolish enough to mention what I do for a living, is: what is my favourite language? I have no short answer for that.

For the non-technical inquisitor, I try to offer a metaphor.  What does a carpenter say when asked what his favourite tool is? Does he tell you that he loves his hammer best?  That his skill-saw is suitable to his every task? I certainly hope not. If he does, I'm sure not going to hire him.  I would expect him to tell me that his hammer is best when there are nails to drive, the saw where there are beams to trim.  The typical carpenter owns a large tool chest, both wide and deep, packed with all sorts of contrivance, both familiar and obscure.  It includes the tape measure which is always at hand, the level and the plumb line which are needed every day; it also includes some odd looking contrivances, rarely used but for particular types of work they are exactly the right thing.

It is long proven that any Turing-complete machine can emulate any other Turing-complete machine.  As pretty much all modern programming languages are Turing complete, any given language can perform every possible task that can be performed by any other language.  In practice there are some limitations to the application of this theory, but it is essentially correct. So it is possible for a programmer to tackle anything equipped with nothing more than one programming language, a single tool for every task.

Does this mean that a serious programmer should be content with the first wooden hammer they learn how to swing? Perhaps we could answer that if we take a moment to reflect on why the current proliferation of programming languages exist.

The invention of assembler should need no explanation; directly inputting machine code is monotonous and error-prone.  The interests of both efficiency and sanity were best served by the creation of a symbolic language for addressing the machine. Then we had a human-readable (so it was held) means for instructing our machines. Theoretically, as assembler is Turing-complete (it has to be or we would never have been able to implement any of our higher-level languages upon it), it could be used to implement any computable task but there are several obvious limitations.

Assembler is very much bound to the specific processing unit for which it is designed.  As different processors may perform the same operation in vastly different ways, there is nothing portable about it. As the complexity of requirements began to grow at an exponential rate (as they continue to through this day, thanks again Mr. Moore), it proved to be extremely expensive in terms of man-hours to build the applications then in demand.

The greatest challenge in writing assembler is unfair to refer to as a limitation or a weakness, as it speaks to it's very nature: assembler requires the human programmer to translate the logic of any given problem down to a mechanical level that the machine can follow.

Humans thrive on abstractions.  We pour over maps, devour books, drink in media, all of it abstractions; all of it carefully produced representations of someone else's abstract thought. All efforts at notation made over the many thousands of years of our civilized history have been efforts to record thought into a permanent form to be revisited or reused.  This is as true for the granary records the Sumerians pressed into clay as for the musical notation of European medieval monks.

Mathematicians have been taking advantage of this for quite some time.  Much of the history of mathematics is the history of mathematical notation.  Ken Iverson's essay Notation As A Tool Of Thought demonstrates how our ability to think is enhanced and empowered by the use of notations which are able to encapsulate powerful concepts into unambiguous representations. Ideas which were once unwieldy can be reduced to symbols and become the bricks of a grander edifice. So proceeds much of our scientific and cultural history.

It was quickly seen (anticipated, in fact) that it would be far more convenient to create high-level notations more akin to patterns of human thought rather than to the machines mechanical dialect.  If such a notation is clear, unambiguous and sufficiently complete as to be able to describe a domain problem fully then it should be possible to implement it as a tool to automate that solution.

As patterns of thought are many and diverse, so it is with the the notations devised to express them. In the 1970s, we find RPG, APL, C (and yacc/lex) and Smalltalk all well-established with Scheme and awk gaining attention. The 1980s brought C++, Objective-C and perl each with passionate advocates and adherents before the 90s came along and blew up the scene. JavaJavaScriptPHPPythonRuby and Lua have become serious contenders in all kinds of software development and particularly dominate the web. Each of these languages sports features which make them compelling and highly suitable for particular tasks.

This is not to say that each generation throws out the languages and paradigms of the previous decade. The best tools evolve over time, often in useful directions attaining the maturity that invites investment. According to the TIOBE Programming Community Index, C continues to be the single most commonly used language in the development of software showing a slight increase over this time last year (as of May 2013). It is followed closely by Java and a group of C variants further down (objective,++,#) before we find PHP at #6 with around 5.8% of the market.  python, ruby and perl all come in at less than 5% before dropping off into little boutiques of groovy, XSL, R J/APL and many others, all of them doing useful work with the best tools available for the task. 

Recommending what languages are best used for new software projects depends very much on the domain.  One can not answer that question without first analyzing the requirements, determining the problem to be solved and selecting a language which is well suited to describing that problem. 

Language adherents often gather themselves into heterogeneous camps eschewing all others, confident that their tools can deliver anything that any other language or tool set can deliver.  What that misses is the education gained from seeing a familiar task undertaken in a completely unfamiliar way.  It stimulates the mind and forces you to consider new possibilities. It will teach you to stretch familiar environments in ways that you had never previously considered.

1 comment: