Flirtin' with Forth

I was a senior in high-school in the mid-1980’s when I first encountered a dialect of the Forth programming language. I was quite familiar with BASIC and Z-80 assembly-language and was just beginning to hand-assemble some 6502 code.

One of my instructors brought in King Microware Tiny Forth for the Commodore 64 computer in her lab.

I was intrigued, at first, and tried to tinker with Forth. The booklet that came with Tiny Forth described the following line of code that I was supposed to enter at the OK prompt:

: SQR DUP * . ;

Then, I was instructed to type:

4 SQR

…followed by the RETURN key. When I did, the system responded with:

16 OK

I was aware that I’d just typed in a function that would square and display the value passed into it. I did not however, understand the importance of everything related to what I had just done. The Forth interpreter had allowed me to interact with it to create the function or more appropriately the word SQR. I could interactively begin to build systems from the bottom up using this technique, but this fact had eluded me.

The booklet that came with the compiler stated that one would have to purchase a book on Forth to explore further. That booklet contained a list of built-in words and not much else.

Lacking a decent Forth tutorial, my attention went on to other compilers, assemblers, and interpreters.

After graduation, I bought my own Commodore 64. I began to purchase several magazines specializing in the Commodore 8-bit family of computers. In one of them, I saw an ad for Superforth64 from a company called Parsec Research.

The ad made a number of amazing claims about Superforth64. These two diagrams included in the ad piqued my interest:

The ad claimed that the Superforth64 language was more powerful than most other languages and more compact than assembled code. Unfortunately, the price for the software was out of my range. I made do writing BASIC with machine-code subroutines for a while. I chastised myself for not studying Forth with more intensity when I had the chance.

I had taken a Pascal course in college where my teacher told us that he wrote code in Forth at his day-job. He went on a slight tirade one night when someone asked “What’s Forth like?”

He tried to describe it to us, explaining that it was interactive and allowed one to get a lot done with a little code. I was getting more curious about Forth.

Some time within the next year or so, Scott Ballantyne released a free Forth system for the Commodore 64 called Blazin’ Forth. It made its way around to one of the local bulletin-board systems (BBS’s), where I ended up finding it. I downloaded it and went through some of the examples. The documentation referred to the book Starting Forth by Leo Brodie as a tutorial as the compiler had been written to comply with the exercises in the book.

I decided that it was time to spend a little money. I went to a bookstore and bought Brodie’s book. I went home to tinker.

I could not seem to put the book down once I started walking through the tutorials. The book itself was very interesting. Little cartoons to illustrate the various components of a running Forth system were included.

I learned about Reverse-Polish Notation (RPN) and stack-based arithmetic. I understood how an infix expression could be rewritten as an RPN expression and could be calculated more effectively. I thought of the C-64 BASIC interpreter which re-evaluated mathematical expressions each time it encountered them. Some of the C-64 p-code compilers noted that they rearranged all infix expressions into RPN, so there was nothing further to parse. Evaluation was done by pushing the terms and invoking the correct operators.

I managed to write a small terminal program with Blazin’ Forth in less time than it had taken me with some other compilers. In fact, some of the other compilers’ runtimes interfered somehow with the Non-Maskable Interrupt ( possibly to intercept the Run-Stop/Restore key combination … I don’t remember, exactly ) which interfered with the RS-232 routines.

I was aware that Blazin’ Forth was itself its own Integrated Development Environment. That term (IDE) was not in use, yet. I understood how from a small Forth system, a larger system could then be built in Forth itself, including the IDE.

I took it on faith that Forth could be an operating-system of its own. To be honest, the computers that were within my financial grasp in those days didn’t exactly have what one would now consider to be true operating-systems. They had I/O kernels and could launch BASIC and machine-code programs.

I noted that Blazin’ Forth directly did not contain a GOTO verb, although branching primitives were available to build flow-control constructs. I understood that Forth provided good tools for structured programming.

Although I continued to tinker with Forth, I never really became skilled enough to attempt to write anything major using it.

As I moved on to an MS-DOS machine, I picked up the Laxen-Perry F83 compiler for MS-DOS which I really enjoyed. It seemed to be more stable on my MS-DOS machine than some of the other free Forth systems I was trying to use.

A short time later, I was writing C code in an MS-DOS environment as a profession. I would often use the Microsoft C 5.1 compiler options that would emit mixed C and 8086 assembly code so that I could understand what a particular C function was doing.

Looking at the assembly code, I could see that some of the things I had typed in by hand in Forth code were being done “under the hood” for me at compile-time by the C compiler. If my C code made a call to a function, the parameters would be pushed onto a stack and the function would be called in a way similar to the way a Forth word would be invoked. Undertanding this concept helped me design my first virtual-machine for a small compiler/interpreter I later wrote.

I found a compendium of the 1982 issues of Dr. Dobbs Journal of Software Tools at a used book sale at the public library. I also found Kernighan and Plauger’s Software Tools, the Ratfor edition. I picked up each book for twenty-five cents each.

The DDJ book contained an abundance of Forth-related articles. One of the articles described added a switch-case construct to Forth. I had to read through this a couple of times. You see, one of the more important features of Forth that took me years to understand was that Forth can take over the input stream at compile-time, allowing the author to completely alter the syntax.

Using languages like C, I envisioned extensibility being limited to using functions as building-blocks. Forth had offered something new; the author can completely change the way a true Forth system treats code.

I later found some interesting uses of this technique. I happened upon some code that implemented an infix expression compiler in Forth. The word infix would parse a math expression in a format more familiar to BASIC programmers. Once parsed, the infix word would then generate the underlying RPN forth code to evaluate the expression. I was discovering that Forth had macro capabilities; smaller snippets of Forth code could be translated into larger blocks of code. This is the equivalent of the modern concept of a DSL ( Domain-Specific Language. )

As MS-DOS BASIC compiler vendors began to advertise better/faster compilers, they began to boast about features such as using threaded-code. A concept that one vendor mentioned learning about when using the Forth programming languages.

As I began to use C++ I found that the concept of namespaces was similar to what Forth offered with vocabularies.

When I used the Eclipse IDE to write Java code, I found that one of the often-cited features of Eclipse was incremental compilation. Forth did that for me ages ago, with a smaller footprint. Granted, there’s a lot more metadata that Eclipse has to keep track of with a given Java module, but the execution of that concept in Forth seemed to be a forgotten piece of history.

I’ve implemented a few Forth-in-C style Forths. Some of them were simple command-interpreters that would use a stack for operations so that I could debug some problems on machines where my IDE wasn’t available. I would expose embedded mini-Forths so that I could evaluate problems at their source.

I’d later written a stand-alone Forth-like language called FIF ( see: https://jimlawless.net/posts/fif/ ). I had intended to use FIF internally in some programs that I sell, but I had not made it efficient enough for some of my needs.

While I have never really gone on to write anything major in any dialect of Forth, I remain astounded by its simplicity and efficiency and its introduction of paradigms that took longer to catch on in other parts of the programming mainstream.