<quote>
Forth has a bad reputation as a computer language. I am embarrassed to even
tell people (who know about computer languages) that I use it, or try to use
it. To admit to using Forth almost seems like the admission of a mild mental
disturbance, but as the decades have ticked over, my appreciation of the
profundity of the ideas behind a Forth system has continued to grow.
We have now a set of modern foundational computer languages that attempt to
provide memory safety while avoiding the complexities of a memory “garbage” collector". To name two: rust and zig. Judging by their popularity and
rapid growth, they must work well. The rust compiler has a good old
fashioned “calvinist” compiler, that reprehends you for your failings.
It admonishes you with fatal errors and illegal memory accesses,
accuses you of sharing references and abusing ownership. The only
thing it lacks is a whip with which you could self-flagellate.
All this pain and punishment, however, must be worth it, since
many of the big software companies seem to be heading in the direction
of rust.
But what does all this have to do with the Forth language? The difficult
problems in designing a language compiler seem to be memory safety,
garbage collection and concurrency. Memory safety is just packing bytes
in the right spot, and not repacking them in the same spot unless
you mean to. You don't need a PHD in anything to understand what needs
to happen, but turning the phrase “replace all instances of ” 'he' with 'she' in 'hehehe'" into memory-safe and fast computer
machine code involves a whole set of decisions about what is
important to you, and what will be important to the person who will
use your language.
But what does all this have to do with the Forth language? Well, Forth
does none of this. Absolutely nothing. It let's you peek and poke
bytes where-ever makes you happy. It makes not the slightest pretence
at being memory-safe, nor does it give you any mechanism for
concurrency. Actually, Forth doesn't really have any 'syntax' , unless
you call words separated by spaces syntax, and so we should probably
stop calling it a language at all.
: gcd ( a b -- n ) begin dup while tuck mod repeat drop ;
Forth is pretty close to backwards-lisp-without-brackets. The only way to
read standard forth is to keep the stack in mind as you read each word, and
frankly, that is not so easy unless you are exceptionally good at activities
like blindfold chess. So why would anybody in possession of their full
faculties decide to use this antiquated, outmoded, obsolete, obfuscated
language to communicate with a computer or with another human being?
The answer lies in the simplicity and profundity of the ideas behind
forth, not in the language itself. Let's start with the Forth compiler:
there is none. Take, for example the comment-syntax above “( ...)” .
The Forth system will probably ignore what is between the 2 brackets,
or at least, it will not execute it as code. So, you may be thinking
“so the FORTH compiler strips out the text between ( and ) and ” then executes the rest" but you would be wrong because there is no
compiler. In fact, “(” is an executable/interpretable word which
knows what to do with itself. To put this another way, the function
“(” compiles (or ignores) itself. Now you may be thinking “Well that” sounds complicated" but no, wrong again. It is as simple as the
following line.
: ( [CHAR] ) PARSE 2DROP ; IMMEDIATE
You may, at this point, experience a certain cognitive dissonance, where you
find it hard to believe that what you are staring at actually has any
meaning. The line above is the implementation of the FORTH comment syntax,
written in FORTH, and written in delightful upper-case 1980's source code.
Let's explain this briefly:
forth
(and functions or procedures are normally called “words” in FORTH simply
because FORTH loves to be weird).
FORTH really has no syntax you
can use any character for anything: no rules, no guardrails,
no babysitting.
FORTH data stack -
the same one that
is in Bitcoin Script or Postscript, or OpenFirmware, or even the
semi-hidden Lisp stack. FORTH normally has 2 stacks but the data
stack is the easiest to use.
FORTH ideas, Charles Moore, realised
that “state” was the one significant semantic complexity of FORTH
(although it is not an implementation complexity) and he tried to
remove it completely in later implementations.
FORTH compiler doesn't
mandate what is or is not a comment. If you read the source-code for some
FORTH-like systems, you will see the line above, and then you will see a
phrase like “( and now we can use comments)” . Don't be surprised if you feel
slightly blown away by this, because what you are watching is the
compiler-system booting itself up, adding to it’s own syntax, evolving
into something new and more language-like.
Perhaps you are under underwhelmed by my description: “So? Its still an ” old impractical language, with no regular expression library."
At this point, I would like to emphasise that the entire system
can be implemented in less than 512 bytes. 512 bytes as in 512 times 8
bits of data. That is quite small, and in that tiny space, you get
a way to read input, print output, execute functions,
create new functions, and use 2 stacks. Those less-than-512 bytes are
running on your computer which has nothing else on it. No operating-system,
no boot loader, just the FORTH machine code.
This really is radical simplicity and it is a type of revolution because it suddenly provokes the thought “You mean to say I didn't actually need all” the other stuff? Really?". No, you didn't need the Jetmaster jacuzzi 2000, nor the 3-car garage with the automatic roller-door, nor the Insinkerator, nor the long long list of economy-stimulating dumb inventions that our/my culture specialises in. All along, all you needed was a sunny day lying in the meadow watching the puffy white clouds pass overhead, and 512 bytes of a FORTH-like system to play with instead of a crossword puzzle, and none of it really matters because it’s the idea that counts, not what you do with it.
So why on earth would you write code in this strange time-warp language
that hardly anybody uses anymore? The answer is, because the purpose
of a machine is to stimulate your thoughts, not to do your thinking
for you. People think about machines because they are worthy of thought,
and a thinking-machine is also worthy of thinking about. Forth is
just an idea, not an implementation. Its up to you to rethink the
system, to make it simpler or stranger or completely different, but
don't throw away the ideas just because you don't understand them.
It is not your job to sit on a committee and tell others how to think
or how to code. The only standard that matters is the name. Name things
well and other people will use your names and they will become
part of the language.
Forth doesn't propose any solutions to memory-management or concurrency, or
really anything else, because it allows you to take your own path. The only
way to use a circular saw safely is to use a circular saw safely, which
means that you have to find your own techniques and procedures that always
ensure that you are not endangering your life and limb. The same may apply
to packing bytes into a digital logic machine. If your code needs to fly an
æroplane or run a life-support machine, are you really going to trust
somebody else's compiler which you don't and maybe can't understand?
Forth encourages you to constantly reappraise and reassess which may
be irritating but is actually desirable when dealing with technology
because one key question will always be “Do we really need this?” .
If you can use a stick don't use a boomerang because a boomerang has
a cost in terms of time and maintenance.