Thursday, June 30, 2011

Progress in Programming Languages

Many people recognize one form of progress in programming language design: the addition of new features, usually forming higher levels of abstraction. Less recognized is the dual of this form of progress: the removal of older, usually lower level, features and freedoms. Paradoxically the removal of language freedoms frees the mind to concentrate on more important parts of the problem at hand.

The earliest programming languages, assembly languages, provided unlimited freedom at a micro level. As an example, each developer was able (actually required) to invent their own conventions for calling subroutines. They could pass parameters in (their own choice of) processor registers, or on a stack (ascending or descending), or in memory structures on a heap. Each of these techniques had benefits and drawbacks, but in the end it was more important to standardize so that developers could share libraries of common modules and free up cognitive space for other issues.

At a higher level, the C programming language (plus the operating system binary formats) standardized routine calling conventions, but left freedoms as to where variables are located and how they are passed. C provides primitive types and records, locates them on the stack or heap, and supports direct memory pointers and pointer manipulation. C++ adds slightly safer references, while retaining pointers. Java, safer and at a higher level, takes away pointers and leaves only references. Much of the safety becomes possible (and necessary) once memory garbage collection is added and low-level memory control is taken away.

Other higher-level languages continue this pattern of addition and subtraction. Python and Ruby add lists and dictionaries as built-in types, and take away direct use of native hardware types.

Perl (yes, the topic of this post) is the oddball. It added many beneficial higher-level features later found in Python and Ruby, but did not remove the low-level freedoms of C++ or even assembly. Like assembly, Perl does not have a single built-in way to pass arguments to functions; instead "there's more than one way to do it" (the Perl motto) so users of CPAN libraries need to pay attention to the calling conventions for each library [and the common ways to do it, @_ and shift, are ridiculous]. Like C++, Perl has references. It needs these because it allows objects to reside on either the stack or heap. But there is no good reason for this distinction in a high-level garbage collected language, and it forces the programmer to explicitly reference (take address-of) and dereference using \, $, etc. (like & and * for C pointers!). Even Java references don't require explicit dereferencing and disallow address-of.

Perl has these issues partly because it was an early introducer of new higher-level features, and didn't want to break compatibility with older Perl programs by removing lower-level functionality and freedoms. But this means the language requires much more cognitive space to understand than newer languages like Python and Ruby, and leaves less cognitive space available for solving the problem at hand.

1 comment:

Gemfinder said...

There is a connection to modularity. Programming commands and idioms are themselves modules. The structure of higher level languages hide lower level features, leaving the coder fewer degrees of freedom to connect pieces together than would exist if the modules were open. As with all modular refactoring, in all engineering, the smaller universe of possible design choices generally results in much higher engineer productivity, at some cost to design performance.

Perl isn't modular in the same way, but is modular in a different way : CPAN. The slow accumulation of modules permits a problem-solving scale that might be impossible for most programmers to achieve with Perl otherwise.

This is in contrast with ruby and python, where the languages themselves are sufficiently espressive to permit problem-solving scale without the huge library. This in turn permits hobbyist programmers to do real work. :-)