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
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!