The softwre provided with large computers supplies a hierarchy of languages: the assembler defines the language for describing the compiler and supervisor; the supervisor the language for job control; the compiler the language for application programs; the application program the language for its input. The user may not know, or know of, all these languages: but they are there. They stand between him and his computer, imposing their restrictions on what he can do and what it will cost.
And cost it does, for this vast hierarchy of languages requires a huge investment of man and machine time to produce, and an equally large effort to maintain. The cost of documenting these programs and of reading the documentation is enormous. And after all this effort the programs are still full of bugs, awkward to use and satisfying to no one.
FORTH - A Language for Interactive Computing
I've written many programs over the years. I've tried to write good programs, and I've observed the manner in which I write them rather critically. My goal has been to decrease the effort required and increase the quality produced. In the course of these observations, I've found myself making the same mistakes repeatedly. Mistakes that are obvious in retrospect, but difficult to recognize in context. I thought that if I wrote a prescription for programming, I could at least remind myself of problems. And if the result is of value to me, it should be of value to others...
Programming a Problem-oriented Language
Keep it simple!
The "Basic Principle"
As the number of capabilities you add to a program increases, the complexity of the program increases exponentially. The problem of maintaining compatibility among these capabilities, to say nothing of some sort of internal consistency in the program, can easily get out of hand. You can avoid this if you apply the Basic Principle. You may be acquainted with an operating system that ignored the Basic Principle.
It is very hard to apply. All the pressures, internal and external, conspire to add features to your program. After all, it only takes a half-dozen instructions, so why not? The only opposing pressure is the Basic Principle, and if you ignore it, there is no opposing pressure.
Do no speculate!
Corollary to the Basic Principle
Do no put code in your program that might be used. Do not leave hooks on which you can hang extensions. The things you might want to do are infinite; that means that each as 0 probability of realization. If you need an extension later, you can code it later -- and probably do a better job than if you did it now. And if someone else adds the extension, will he notice the hooks you left? Will you document this aspect of your program?
Do it yourself!
Second corollary to the Basic Principle
The conventional approach, enforced to a greater or lesser extent, is that you shall use a standard subroutine. I say that you should write your own subroutines.
Before you can write your own subroutines, you have to know how. This means, to be practical, that you have written it before; which makes it difficulat to get started. But give it a try. After writing the same subroutine a dozen times on as many computers and languages, you'll be pretty good at it.
Moore followed this to an astounding extent. Throughout the 70's, as he implemented Forth on 18 different CPUs (Table 1), he invariably wrote for each his own assembler, his own disk and terminal drivers, even his own multiply and divide subroutines (on machines that required them, as many did). When there were manufacturer-supplied routines for these functions, he read them for ideas, but never used them verbatim. By knowing exactly how Forth would use these resources, by omitting hooks and generalities, and by sheer skill and experience (he speculated that most multiple/ divide subroutines were written by someone who had never done one before and never would again), his versions were invariably smaller and faster, usually significantly so.