My article on Fortran, This is Not Your Father’s FORTRAN, brought back a lot of memories about the language. It also reminded me of other languages from my time at college and shortly thereafter, say pre-1978.
At that time there were the three original languages – FORTRAN, LISP, and COBOL. These originals are still used although none make the lists of popular languages. I never did any COBOL but did some work with Pascal, Forth, and SNOBOL which are from that era. Of those, SNOBOL quickly faded but the others are still around. SNOBOL was a text processing language that basically lost out to AWK, PERL, and regular expressions. Given how cryptic regular expressions are it’s amazing another language from that time, APL – A Programming Language, didn’t survive. APL was referred to as a ‘write only language’ because it was often easier to simply rewrite a piece of code than to debug it.
Another language deserving mention is Algol, if only because Pascal is a descendant, along with many modern languages. Algol was always more popular outside the US, probably because everyone there stuck with FORTRAN.
Back then certain books held iconic status, much like [McCracken’s] black FORTRAN IV. In the early 70s, mentioning [Nicolas Wirth] or the yellow book brought to mind Pascal. Similarly, [Griswold, (R. E.)] was SNOBOL and a green book. For some reason, [Griswold’s] two co-authors never were mentioned, unlike the later duo of [Kernighan] & [Ritchie] with their white “The C Programming Language”. Seeing that book years later on an Italian coworker’s bookshelf translated to Italian gave my mind a minor boggling. Join me for a walk down the memory lane that got our programming world to where it is today.
The creator of Pascal, [Nicholas Wirth], was something of an iconoclast of his times. Pascal was a rebellion against Algol 60, which he felt was overly complicated and not useful for real work. I’d love to hear his opinion of Java and C++. Working without the constraints of a standards committee he pared Algol down to the bones to create Pascal.
[Wirth] was a hacker at heart:
Every single project was primarily a learning experiment. One learns best when inventing. Only by actually doing a development project can I gain enough familiarity with the intrinsic difficulties and enough confidence that the inherent details can be mastered. – From Programming Language Design To Computer Construction, Niklaus Wirth 1984 ACM A.M. Turing Award Recipient Lecture.
The language was so compact it was completely described and defined in a 58 page book, almost a pamphlet. This included showing it in Backus-Naur Form, and a novel graphic representation that became known as railroad diagrams. Being visually oriented I really liked that representation.
An interesting feature is Pascal was bootstrapped into existence. A bootstrapped language’s compiler is written in itself, using the smallest subset possible. That compiler is then hand written in another language, probably Fortran for that time frame. Once the hand written compiler works you can feed its executable the compiler code written in the new language. Out comes an executable that will now compile itself. From there you can write the additional features in the language itself. Bootstrapping was a boon for computer science students as it provided them with a working compiler they could extend and hack but was still small enough to comprehend.
Pascal was a one pass compiler while almost all other languages make multiple passes through the code or intermediate outputs. This made compilation fast. A drawback was it didn’t provide much optimization.
Some Pascal code:
program ArithFunc; const Sentinel =0.0; var X:Real; begin writeln('After each line enter a real number or 0.0 to stop'); writeln; writeln('X', 'Trunc(x)' :16, 'Round(X)' :10, 'Abs(X)' :10, 'Sqr(X)' :10, 'Sqrt(Abs(X))' :15); readln (X); while X <> Sentinel do begin writeln (Trunc(X) :17, Round(X) :10, Abs(X) :10:2, Sqr(x) :10:2, Sqrt(Abs(X)) :10:2); readln(X); end end.
You can see the relationship of Pascal to current languages like C, C++, and Java, all derived from versions of Algol. One of the big complaints about Pascal is it didn’t use semi-colons enough. You can see in the example there is no semicolon prior to the final end. Another characteristic is the keywords begin and end marked blocks of code, where in today’s languages we use braces.
Pascal is still in use, having gained widespread popularity with the advent of the PC. The first PC compiler used UCSD Pascal P-code, an interpreter engine much like today’s Java. P-code was developed to allow easy porting of the language to new machines, the virtual machine being easier to write than a compiler.
The big boom for Pascal on the PC was the release of Borland’s Turbo Pascal (TP) in 1983. It was cheap so hackers could afford it and it had an integrated programming toolkit, what we’d today call an IDE.
I lay claim to using TP for an early, if not first, industrial usage. A team I led developed the software for an Intel 8088 based flow computer, i.e. an embedded system used to measure the flow in pipelines of gas or liquids. I developed an IDE using TP that generated bytecodes that were downloaded to the flow computer. The remainder of the team developed the flow computer software which included an interpreter for the bytecodes. The system was basically Lotus 1-2-3 – Excel for you youngsters – for pipelines since end users could develop their own code.
Turbo Pascal added object oriented features in the ’90s and finally morphed into Delphi.
SNOBOL was used for processing text and symbols. The name really isn’t meaningful, although some tried to shoehorn acronyms and portmanteaus. Griswold and others were sitting around talking about the name, shooting rubber bands, when they decided they “…didn’t have a snowball’s chance in hell in finding a name.” They shortened ‘snow’ and substituted ‘BOL’, which was the ending for many languages of that time.
(Rubber bands were used on card decks so shooting them was a favorite nerd pastime back then. I shot a cigarette out of a young ladies’ lips with a rubber band once. I was good!)
Here is some code to give you a sense of the language:
OUTPUT = "What is your name?" Username = INPUT Username "J" :S(LOVE) Username "K" :S(HATE) MEH OUTPUT = "Hi, " Username :(END) LOVE OUTPUT = "How nice to meet you, " Username :(END) HATE OUTPUT = "Oh. It's you, " Username END
Like many langauges of the time SNOBOL used a single line card format with a special flag character allowing continuation onto other cards. The first field was a destination label. The middle field contained the programming statements. The right most field, following a ‘:’, was test and jump.
The OUTPUT and INPUT lines are fairly obvious as is the assignment. After the assignment are two lines that perform a pattern match to see if the letters ‘J’ or ‘K’ are in Username. If the letters appear the line succeeds. On success, flagged by the ‘S‘ in the test field, a jump is made to the destination label. You could also ‘F‘ail, do both, or just jump, as shown by the jump to END in the code.
SNOBOL did all the text manipulation you would expect: concatenation, replacement, extraction, etc. It also did the usual math operations.
It was an interesting language to play with; very easy to understand and work with.
Forth is an intriguing language in multiple ways. It came neither from the computer industry nor academia. [Chuck Moore] developed it working a number of jobs but it came to fruition at the National Radio Astronomy Observatory developing embedded systems for the Kitt Peak observatory. From the start, Forth was meant to be portable. When [Chuck] changed jobs he wanted to take his toolkit along.
Forth is a threaded language. In our more traditional languages code is translated into a sequence of real or virtual machine opcodes. The machine then steps through the op-codes. In a threaded language only primitive operations are coded as opcodes. In Forth these primitives are the basic words of the language. All other defined words are built on the primitives.
Instead of opcodes a threaded language stores the address of the word. An inner interpreter in Forth steps through this list of addresses. If the address is that of a primitive word the opcodes are executed. When it is a defined word the inner interpreter jumps to that sequence and begins walking its list of addresses. A word at the end of a sequence causes a return to the previous word definition. The process is straightforward and surprisingly fast. It also makes threaded languages very portable. Once the primitives and the inner interpreter are created Forth is pretty much up and running. All the rest of the language is based on defined words.
An outer interpreter provides the user interface. You simply type in words and they are executed. There are words that allow you to define new words which are added to the dictionary. Revising code when working at the user interface is easy: you just enter the word definition again. The new definition overrides the older definition.
A compilation process walks through the dictionary selecting only the words actually used by other words, strips out all the parts needed for interactive processing, and creates a ‘binary’ containing the primitive and defined words that are needed. This, like the execution speed, is a surprisingly compact representation often smaller than standard compiled code.
Forth is like a giant hand-held calculator from Hewlett Packard: it uses a stack and reverse Polish notation (RPN). To add two numbers you’d enter: 2 3 +. This would push the 2 and 3 onto a stack. The + would pop them and add them leaving the resultant, 5, on the stack. While you can define variables most operations are done using the stack.
Here’s a Forth word definition and example usage for squaring a number:
> : sqr dup * ;
> 2 sqr .
> 3 sqr .
A word definition starts with the colon. The first token after that is the name. It can be anything! Forth often defines some numbers as words because it is actually faster to load the value from a word than convert it. If you want to drive someone nuts you can define 2 as 1 by entering “: 2 1 ;”.
Continuing with the example, the word dup creates a copy of the top of the stack and the ‘*’ multiplies the top two values leaving the resultant on the stack. In the lines where sqr is used the ‘.’ prints the top of the stack and removes the value.
You can try Forth using an online interpreter.
Back in the days of computers using CPM as the OS I wrote a text editor using Forth. The editor allowed the use of cursor keys, delete, insert, etc. It took only an hour. My introduction to Forth was at the University of Rochester Laboratory for Laser Energetics. Forth was used to develop the control system for the large laser fusion experiment they were undertaking. I even went to Manhattan Beach, CA for training at the Forth, Inc. offices. The second Forth programmer in the world, Elizabeth Rather, was my instructor.
Forth is still being used in aerospace and commercial applications.
I suggested in the Fortran article that someone create a FortDuino. I can’t make the same suggestion for Forth since it already exists in multiple incarnations. Besides, that would be fairly easy. It’s what Forth is meant to do. A larger challenge is a PiForth, or ForthPi, running as the operating systems loaded from the SD card. We’ve seen a Lisp version so how about Forth? Now that would be interesting.
I hope you’ve enjoyed these two articles that walked through some history of programming languages from my personal experience. It was fun to bring back the memories and refresh the details by searching the web. The relationships among languages are fascinating, which reminds me of one last story.
The University of Rochester’s computer center, by some quirk, was in the basement of a Holiday Inn on the campus. Jean Sammet, another of the famous ladies in computing history, stayed at the Inn for an ACM conference. She commented that her sleep was disturbed because she kept dreaming of line printers for some strange reason. Nobody had the heart to tell her they may have been right under her room. I recalled this story because one of Jean’s books included a chart of programming language ancestry similar to the chart in the above link.