forth know? if honk else forth learn then
Forth is a stack based threaded interpretive language, that I used to program
in it a whole lot. It has two stacks, unlike most other programming languages
which have one. The operand stack is separate from the return stack. Arguments
are passed on the operand stack, and flow of control is kept track of on
the return stack.
Forth functions are called "words", and they have a header and
a body. The name of a word can be any sequence of non-space characters,
so Forth language documentation always includes a spoken pronunciation for
each word. Other less hieroglyphic programming languages could also benefit
from this convention.
The body of a Forth word typically consists of a sequence of pointers to
other Forth words. This is called "threaded code". Other words
are implemented as machine language primatives. There are different kinds
of Forth interpreters that thread the code in various ways, but the essential
thing about Forth is that code is a list of pointers to more code, which
eventually bottoms out in primatives.
Forth syntax is very weird, yet extremely simple. The Forth compiler is
part of the language, that Forth programmers can easily extend to define
their own programming constructs and macros. Most forth systems also include
an assembler with which you can define machine language primatives. You
can write programatic macros that call the assembler and Forth compiler
to dynamically generate code. Some Forth systems even allow you to dynamically
link and call functions in libraries written in other languages.
Forth takes the "glass
box" approach to language design (as opposed to the "black box"
approach): Forth is essentially very simple, but you have to keep the whole
thing in your head to use it. Forth environments usually provide a good
decompiler that you can use to remind yourself what something does.
Here's a position paper I wrote about
Rapid Prototyping in Interactive Programming Environments,
that describes some of the uses of Forth
The first Forth system I used was Cap'n Software Forth, on the Apple ][,
by John Draper. The first time I met John Draper was when Mike Grant brought
him over to my house, because Mike's mother was fed up with Draper, and
didn't want him staying over any longer. So Mike brought him over to stay
at my house, instead. He had been attending some science fiction convention,
was about to go to the Galopagos Islands, always insisted on doing back
exercises with everyone, got very rude in an elevator when someone lit up
a cigarette, and bragged he could smoke Mike's brother Greg under the table.
In case you're ever at a party, and you have some pot that he wants to smoke
and you just can't get rid of him, try filling up a bowl with some tobacco
and offering it to him. It's a good idea to keep some "emergency tobacco"
on your person at all times whenever attending raves in the bay area. My
mom got fed up too, and ended up driving him all the way to the airport
to get rid of him. On the way, he offered to sell us his extra can of peanuts,
but my mom suggested that he might get hungry later, and that he had better
hold onto them. What tact!
I had a job programming Forth for a little company called "Computer
Challenges", when I was in high school. I implemented my own Forth
programming environment for the Apple ][ computer, and a graphics and animation
package in 6502 assembly. Then I wrote an animated graphics
demo with it, promoting Forth as a cross platform game programming language
across Apple ][, C64, and BBC computers.
(That was more than a few years before Java.)
I designed some video games and animated graphics that used the animation
package, wrote utilities in 6502 assembly, and supported a co-worker writing
educational software using my Forth system.
I ported Forth from DOS 3.3 to ProDOS, adding a real file system interface,
and used it to develop numerous text editors, terminal emulators, a bulletin
board, a file manager, and TypeRite, an intelligent typewriter program.
At the University of Maryland Parallel Processing Lab, I ported Z-80 FIG-Forth
to the ZMob parallel processor. ZMob was "the Computer of the Future,
using the Processor of the Past":
128 Z80 microprocessors in parallel!
When I started programming on Suns, I found out about Mitch Bradley's 68000
forth system, and started using that for all kinds of stuff. He developed
"Forthmacs", a very rich Forth programming environment for the
Sun (based on Langston and Perry's Forth-83), that was my programming environment
of choice for a long time.
The command line interface was very deluxe, with emacs bindings for input
and history editing, with a key to display and fill in possible completions
over the Forth vocabulary. A powerful feature that let me use Forth for
many things I couldn't have done otherwise, was the ability to dynamically
link in compiled C code, and call the functions from Forth. So I could develop
libraries in C, and test them out and drive them from Forth.
Forthmacs eventually evolved into the Open Boot Proms, the
stand-alone boot monitor
you get when you hit L1-A on a Sun, and now it's an IEEE standard,
IEEE 1275 Open Boot Firmware.
Mitch, Michael Parry and Gudrun Polak now work together at
Firmworks,
and continue to develop and support it!
You can even listen to
Mitch Bradley singing the Open Firmware Song!
The first color framebuffer I programmed was a Sun-2 with a "cgone"
graphics board, with Forthmacs, of course. The only documentation I had
was a gnarly header file with a magic structure that was layed out so that
you could map it onto the device registers, access special fields, and the
address bits would be set to the right values to do what you want. Years
later I learned that John Gilmore wrote that header file. I reverse engineered
it, and started programming the graphics board from Forth and reverse
polish notation 60020 assembly language. I made a breshenham
line routine that got its color from a texture map of my face (although
I didn't know it was called a texture map), and bounced a couple points
around the screen drawing lines between them like "qix", ramping
the pixel values, while it did three separate randomly jostling bubble sorts
in the red, green, and blue components of the colormap. It looked weird!
I made my first multithreaded programmable window
manager with pie menus, by breaking
open the inner loop of a C window manager (X10 "uwm"), linking
it into Forthmacs, and writing code in Forth that could create and pop up
menus, track the mouse, and call into and delegate events to the window
manager code.
We used it to administer, time, and record statistics for the experiment
we did, comparing pie menus and linear menus. At one point, I wrote code
that would let you throw a window and it would bounce around the screen,
by starting a Forth thread that pushed it around. You could have a whole
bunch of windows boucing around the screen and frantically repainting at
once! I can't believe how well it performed on a little Sun 3/160, compared
to how slow and bloated computers are today.
This multitasking Forth programmable window manager forshadowed my work
with NeWS, a window manager programmable in multithreaded
PostScript, another stack based language. Mike Gallaher and I went to visit
Sun, and I read the Red PostScript book on the plane. I met the likes of
Gilmore, Gosling, Rosenthal, Densmore, and Bradley (who later hired me as
a summer intern), and finally saw and promptly crashed my first NeWS server
(then called SunDew).
The next summer I went to work at Sun as Mitch's summer intern, and we integrated
his "C-Forth" into "CADroid" and wrote a higher level
user friendly extension language for that circuit design tool in Forth.
Mitch came up with and I implemented a great way to integrate the "if/then/else"
and the "for arg = 1 to n" control constructs into a simple and
practical "repeat/else" syntax: "arg [ stuff to repeat arg
times ][ stuff to do if arg is 0 ]". You could program macros by demonstration,
walking through and recording a sequence of steps, and it would prompt you
in english for arguments to commands, which you could fill in either as
constants (that were recorded in the macro) or descriptive prompts for run
time arguments (with which you were then re-prompted). It was pretty neat,
because you could walk through the first iteration of a loop, then record
an else clause without effecting the drawing, then close off the loop, and
it would chunk through the freshly compiled forth code executing the rest
of the arg-1 iterations really fast! All of the movement commands were relative,
so they could be meaningfully recorded in macros.
Later, when we were developing the Unix version of HyperTIES (a hypermedia
browser) at Ben Shneiderman's Human Computer Interaction Lab, I used Forthmacs
to prototype the HyperTIES hypermedia engine. I developed a hypermedia formatter
library in C, that downloaded PostScript page descriptions to NeWS.
To test it, I linked the library into Forthmacs. In Forth, I defined a sealed
vocabulary of formatting commands that interfaced to the library, then defined
the Forth "unknown word" handler to send the word to the formatter.
So we could write a web of HyperTIES pages in this new markup language,
which would run through the Forth interpreter in the sealed vocabulary,
which called into the C library linked into Forth, that downloaded PostScript
to NeWS.
The PostScript code, running in the NeWS window system's interpreter, displayed
formatted text, graphics, and interactive user interface components. Graphical
"embedded menus" (now called "image maps") gave
interactive feedback when you moved the mouse over them,
by popping up a cut out magnified image with a drop shadow.
You could click on the background and all the targets would
pop up at once! You could click once on a link to get a definition
(since every node had a short descriptive definition), and double
click to follow the link.
The interactive front-end running in the NeWS server could send HyperTIES
commands back to the formatter engine, in response to user input,
to display definitions, follow links, run programs, etc.
HyperTIES pages could contain formatted text, images,
buttons, text editors, pie menus, font and color selectors, and other kinds
of user interface components and NeWS "applets" written
in PostScript.
This was before the days of HTML.
I suggested that we consider using SGML as our markup language,
but instead we decided to go the route of designing our own language.
We required constructs that SGML did not support, like macros,
if statements, and environment variables.
The HyperTIES markup language allowed you to describe conditional text,
adaptive documents, parameterized templates, etc.
Then I wrote an authoring tool in "MockLisp" using UniPress Emacs,
that drove the hypermedia engine around as a sub-process, and let you navigate
and edit the source content as text. I needed hash tables, but the closest
thing Emacs had to them were "abbrevs" -- abbreviation tables.
So in order to implement each master index, that mapped between identifiers
and files, I had to make a buffer with a local abbrev table, and the text
of the master index so I could do the reverse lookup using text search.
By now you
unix haters
may be grasping for your
barf bag, but back in those days,
I was a unix weenie, and we just did stuff like that to gross each other
out, kind of like kids turn their eyelids inside out and pick their noses
at each other in the lunch room. But at least it was never installed in
an air traffic control, weapons command, or life support situation! Think
of all those mission critical NetScape Nagivators out there, just waiting
for the right moment to explode!