The Stainless Steel Rat's Jump Pad

Home | Other Items of Interest | Programming Languages | Hackers | What's Wrong with Microsoft | Table of Contents

Computer Languages: One's Person's Views

Many different computer languages exist, for many different reasons. No matter what language you despise, someone else thinks its the greatest thing since sliced bread; you would do well to remember this when you talk about other computer languages.

These, too, are my own personal biases, and are informally based. Some opinions are based on having used a language with some frequency; others are based on "book-learning" and "exposure" to the language rather than any in-depth usage and study. This is not a comprehensive listing of languages by any means, but most popular languages should be listed. These languages are basically my favorites (and occasionally, flops that I've endured).

What's Wrong with Computer Languages Today

There are many problems with the languages that exist today. For some reason, no one has seemed to notice. These are the main ones:

Unnecessarily Strange and Complex Syntax

This happens a lot; however, any computer language will look strange. This problem mainly occurs in languages that try to follow the ALGOL model (such as Pascal, C, FORTRAN) but which break the syntax in strange and bizzare ways for no good reason (Sather).

This does not apply to languages that do not adhere to any traditional (ie, ALGOL) syntax but create their own (such as FORTH, Smalltalk, LISP, or APL). These languages require a programmer to think differently and were original creations, not spin-offs - a non-ALGOL syntax forces the programmer to think differently and to learn a new way to program.

Compiling to Another High-Level Language

Some languages (Sather, Linda) will fool you into thinking you are writing in a new language where in reality it is only a pre-processor for another compiler (usually a C compiler). Why not program directly in C in such a situation? The program can be optimized, and an entire compile step can be avoided, saving development time.

Lack of Scoping

This may sound somewhat esoteric and possibly seem a minor point. Some languages just "assume" that a control construct terminating keyword automatically goes back to the most recent control construct, removing from the programmer any chance to modify the scope. This problem is unheard of in most modern languages; a few old ones have this problem (most notibly, COBOL).

To explain better, let's compare a code fragment from C, FORTH, and COBOL:

C FORTH COBOL
if (valve == OPEN) {
   if (temp > MAXTEMP) {
      printf("HOT!\n");
      }
else {
   printf("Valve closed.\n");
   }
}
VALVE ?OPEN IF
   TEMP @ MAXTEMP > IF
      ." HOT!"
   ENDIF
ELSE
   ." Valve closed."
ENDIF
IF VALVE EQUALS OPEN
   IF TEMP GREATER THAN MAXTEMP
      DISPLAY "HOT!"
   ELSE
      NEXT SENTENCE
ELSE
   DISPLAY "Valve closed.".

The COBOL statement NEXT SENTENCE is required in this situation (and others like it). Otherwise, the last ELSE would match up with the wrong IF statement, causing all sorts of havok. In C, the innermost if statement is terminated by a curly bracket; in FORTH, the same inner IF is terminated by an ENDIF. Newer versions of COBOL (like the last 20 years!) don't have this problem.

Interpreters

For development, an interpreter can be helpful; but without a true compiler such a language is a waste of time. The most often cited example of a language has been traditionally in this genre is BASIC - which is in many respects unfair, since BASIC has matured and many high-quality compiled BASIC implementations exist. BASIC is however, by no means the only interpreted language.

This rant against interpreters does not apply to "low-level" interpreters, such as the Smalltalk byte-code interpreter, the FORTH inner interpreter, or the UCSD Pascal p-Code interpreter. These interpreters implement a "virtual machine" for their respective languages; such interpreters can be a plus (if designed and implemented properly). I would suggest that the FORTH inner interpreter is very clean and slick, the Smalltalk byte-code interpreter is probably well done, and the UCSD p-Code interpreter was a part of what lead to the (unfortunate) demise of UCSD Pascal.

OS Interaction - and File Input/Output in Particular

It would be better if each language established its own standard set of routines. However, it seems each implementation has their own set of routines. A set of FORTH words to do MSDOS file I/O in one FORTH environment will be completely different from a set in another MSDOS FORTH environment, not to mention other OS environments entirely (such as UNIX, OS-9, Pick, Windows NT, etc.). C comes closest to adhering to a standard set of file IO; FORTH tried to and everybody had to go and break it.

In fact, the "skeleton" that many language programmers use probably contains mostly file I/O set up; in COBOL, it seems that that is most of what is contained in many programmer's program skeletons. I know every time I wrote a COBOL program, file I/O was the biggest obstacle and was resolved by a good program skeleton from a previous program.

To me, this is the biggest hurdle in learning any language. There is no shortage of so-called "tutorials" that teach you how to do everything except important operations like:

Creating a turnkey application is absent from even more tutorials and introductions than is file input/output. What good is a tutorial or introduction unless you can create a program fergoshsakes! Sometimes, I suspect that these "introductions" are merely for people who want to study a language (like one studies a frog) and not for real programmers.

To me, the four items list above are critical to know; a tutorial which does not include them is at best incomplete.

The Language Comparisons

Smalltalk

Personally, I believe that Smalltalk is the finest implementation of the object-oriented philosophy there is. I have been disappointed with every other so-called "object-oriented" language which all seem to have made one compromise ("enhancement") or another. Every item is an object, including numbers, strings, and procedures, and every "operator" or "procedure call" is actually a message being sent to an object.

C

C is a very fine traditional language. It isn't the first language I might prefer to use on a daily basis but it is the one I chose when the time comes. Like FORTH, it permits you to "program to the metal." However, it suffers from the traditional language model of the "edit-compile-run-debug" sequence, which dramatically slows down development time. One of its advantages is the conciseness of the language: there are only 28 keywords last I checked. Other strengths include its standard I/O library, amount of code and utilities, and portability.

FORTH

In my mind, this is one of the finest languages there is. It allows the programmer to program "to the metal", while at the same time providing for rapid prototyping. Programs can be developed quickly and tested easily, and each "procedure" (or "word" in FORTH parlance) is practically a "micro-procedure" compared to any other language. Everything in FORTH is a word, including compilers, language flow constructs, numeric base specification, assemblers, the FORTH interpreter, and everything else. There are no procedures, functions, statements; there are only words. FORTH can run almost anywhere, in cramped space and/or in ROM. However, FORTH can also explode with an overwhelming number of FORTH words to learn - in one implementation I worked on, I counted 300+ FORTH words.

Pascal

Pascal is a nice language, but traditional Pascal is too limiting, and prevents the user from doing much too many programs that require low-level machine or operating system access. Turbo Pascal blew away these limits on the IBM PC; on the Apple II Kyan Pascal was one of the hottest compilers I've seen - it ran very fast - and on the Apple IIe series no less.

C++

C++ is okay, but it always struck me as looking a lot like a "see-through" Smalltalk - that is, it has an object-oriented ideology with all the guts hanging out. I found myself having to use three or four different names for what should have been a single object. I would rather not do my OO programming in C++ if I can help it.

Sather

Sather has to be one of the first languages I've seen that makes case-dependency a part of the language (which does not bode well for this language). It has an unnecessarily strange syntax, including an extensive set of user-definable looping structures. The big question that comes to mind is WHY?

Logo

Logo is nice, and has a very clean syntax. Programming in it is easy to learn and pleasant. It is unclear to me, however, how much production use this language has seen outside of its stated child education role.

BASIC

BASIC is a much maligned language, unfairly I think. Most people seem to have confused the language with the implementation. There have been many poor implementations, but also many high-quality top-rate implementations as well (Waterloo BASIC comes to mind, or True BASIC). Because of its poor image, the high-quality BASIC implementations did not sell, and new implementations tended to gravitate further and further toward the poor side - since no one probably wanted to spend any money on such an unpopular language.

Perl

Perl is probably one of the most powerful scripting languages available for the UNIX platform (and others) that there is. It is extremely flexible and powerful, and some large and scary applications have been developed in this interpreted language. It has the benefit of being free - since the original was released under the GNU copyleft by its creator - and available on almost any platform, most likely because of the source code being freely available.

LISP and Scheme

LISP (and its descendent, Scheme) require some adjustment on the part of the programmer. Unlike many other modern languages, there doesn't seem to be any standard file input/output operations; perhaps this has changed in Common LISP. LISP is a clean language with a clean syntax. However, most tutorials and learning facilities seem to think that writing "Animal" or "Eliza" is important, rather than attempting to write a simple language compiler or a factory automation system or an inventory control system. The LISP community seems to be lacking in real-world examples - but that may just be my lack of exposure to LISP.

COBOL

COBOL is another language which has been much misaligned, in some ways unfairly. Many people will have heard how horrible it is; few of them will have actually programmed in COBOL to find its strengths and weaknesses. COBOL's SORT function is very powerful, and the syntax is very - very - simple: what is more simple than SUBTRACT A FROM B GIVING C. (complete with period, no less!). This wordiness also works against COBOL, making even the smallest COBOL program balloon in size; a printout of a large project could weigh more than a small child! COBOL also has had problems in scoping, and in file input/output. Its method of defining data areas is a weakness, with arrays being a particularly notable missing or poorly implemented feature.

Some of the language's problems are being solved through the current attempt at ANSI standardization and new language features; COBOL is by no means dead, but is widely used and continues to evolve with new and modern features. The biggest revolution in COBOL seems to be ANSI Standard Object COBOL, introducing object-oriented programming to COBOL.