Forth Language

Local Wiki Resources:

Starting Forth:
The classic Forth and programming tutorial by Leo Brodie

Thinking Forth:
The classic Forth book by Leo Brodie

Example Forth Code:
A few simple examples of FORTH code, to give you a minimal feel for it.

Chuck Moore:
The inventor of Forth, Color Forth, and Forth Processors

Forth Values:
Core values of Forth from 1970 to 1999

Forth Simplicity:
Explains the extreme simplicity of Forth

Forth Readability:
Shows how easily one can read each other's code

Forth Efficiency:
Examples of Forth's efficient use of resources

Forth Reusability:
Shows how effective code sharing can be

Forth Portability:
Proves how easily you can move your code from one platform to the next

Forth Objects:
Object-Orientation in Forth, with a sample implementation (see also Mops Language and Neon Language)

Forth Scientific Library:
Scientific and mathematical abstractions

Forth In Smalltalk:
Ward Cunningham relates an educational experience with his brother

Smalltalk In Forth:
Attempting to implement Smalltalk in Forth

Forth In Java:
... rumors of Forth running on top of the Java Virtual Machine ...

Post Script:
A closely related language that is optimized for printing (see Forth Postscript Relationship)

Forth Community:
the users of Forth

Forth Wiki Projects:
Forth Wiki originated projects covering a range as wide as their contributor's horizons

Forth Vs Lisp:
A comparison of the two languages.

Forth Macro:
Extending the language.

Ans Forth:
the 1994 ANSI standard for Forth to which most modern systems comply

Open Firmware:
A Forth system built into the firmware of every Sun and Apple computer, as well as many servers from IBM.

Factor Language:
another Post Fix language borrowing ideas from Common Lisp and Forth

Forth In Lua:
Forth is implemented in Lua Language

Getting Started With Forth:

Starting Forth:
Leo Brodie's classic Forth and programming tutorial. Now with modernized online versions.

www.sunterr.demon.co.uk :
Guide to getting started with Win32Forth (includes download locations and introductory tutorials)

www.geocities.com :
Forth in Java (This page includes eForth implemented as a Java applet, allowing any Java-enabled browser to try Forth interactively. (Java source (160K) is also included))

Js Forth :
Forth in Java Script, running in a web browser window

wiki.forthfreak.net :
online tutorials

Discussing Forth with others: IRC and other Forth-related wiki: (Edit Hint: move to Forth Wiki ?)

news:comp.lang.forth :
The Use Net newsgroup for Forth.

wiki.forthfreak.net :
Forthfreak - a Forth-specific wiki with an inventory of many Forth resources

Sleepless Night Wiki :
a wiki focused on Quartus Forth, but with many general purpose pages as well

#forth@irc.freenode.net (openprojects is now freenode):
Introduction to irc at www.mirc.com

wiki.enst.fr :
Pic Forth - a wiki focused on Pic Forth, which runs on those little under-$8 PIC microprocessors with ~8K words of program memory and a few hundred bytes of RAM ... unfortunately, not (yet) interactive. Is there something similar for the Atmel AVR? -- David Cary

There is a free system called AVR-Byte Forth by Willem Ouwerkerk, but I don't have an address. Also see www.tinyboot.com . And both Forth Inc and MPE have commercial AVR compilers and dev systems, including free eval systems. -- Ian Osgood

annexia.org :
Jones Forth - A concise, wonderfully well-commented Forth implementation in assembly. Reads like a novel.

www.forthwiki.com :
Much more than just a wiki. FAQs, Forums, Articles, Blogs, Links and more.

Other Internet Resources:

www.forth.com :
A full history of Forth

www.taygeta.com :
The Taygeta archive of Forth resources

www.forth.com :
(Forth, Inc.) Forth Inc was the first company to sell Forth products, and was founded by the inventors of Forth.

www.ultratechnology.com :
Recent work on hardware Forths, includes recent talks by Charles Moore

www.forth.org :
The Forth Interest Group

dec.bournemouth.ac.uk :
The Forth Research Page

www.zetetics.com :
Good papers on Forth implementation

forth.gsfc.nasa.gov :
Lists over 50 space-related uses of Forth

dmoz.org :
The Open Directory Project listing for Forth

dir.yahoo.com :
The Yahoo listing for Forth

www.zforth.com :
The Forth Programming Webring

www.fig-uk.org :
How to implement your own Forth

www.quartus.net :
Quartus Forth for the Palm - A whole development system self-contained on a Palm

www2.tunes.org :
Forth as OS

home.vrweb.de :
Strong Forth, a Forth dialect with strong type checking

rainbowforth.sourceforge.net :
An AJAX-y implementation of Color Forth called Rainbow Forth.


How did Forth get its name?

Charles Moore::
The first time I combined the ideas I had been developing into a single entity, I was working on an IBM 1130, a "third-generation" computer. The result seemed so powerful that I considered it a "fourth generation computer language." I would have called it Fourth, except that the 1130 permitted only five-character identifiers. So Fourth became Forth, a nicer play on words anyway.


Forth is a Stack Based Language based on Postfix Notation: Operations and function calls are placed after their arguments. They work by popping the arguments off the data stack, performing their operation, and then pushing the results back on the data stack.

FORTH is often used in Embedded Systems:

It packs LOTS of functionality into limited memory.

Code (and much data) is ROM-able.

Is a "High Level Language" that encourages highly modular code. (OO in later releases.) (See High Level Language below)

Can be interpreted at high speed (approaching that of machine code). Think "interactive hardware debugging".

Easily compiled to machine code (but this is not usually done in most free implementations; only professional ones like Forth Inc, MPE, and Quartus Forth).

Integrated access to assembly language.

Is "fully and easily extensible." (Only a few low-level routines of the runtime are not written in FORTH.)

The boot monitor on Sun Microsystems workstations includes a very useful Forth Language interpreter (Open Firmware). Hours Of Fun. (The "stars" sample code at Example Forth Code works at the "ok" boot prompt of any Sun workstation.)

In the 80s, Forth was also commonly used by astronomers (and their grad students!) to program the control systems of telescopes and other instruments. I don't have recent data to know if this is still the case.

Originally, Forth was a Threaded Interpretive Language. Among the variations used:

These are fast, easy to implement, and allow very compact object code. Modern professional Forth implementations do optimized compilation.


FORTH is a "High Level Language" that encourages highly modular code. (OO in later releases.) (About the same level of abstraction as C?)

(Realize that "higher level" is not always a good thing, as the most "high level" of languages are always specialized for particular domains, and work poorly in other domains.)

To address the question, I'd say that FORTH is slightly "lower level" than C. Knowing the workings of the interpreter, and manipulation of the virtual machine state are typical of FORTH programming. And the ease of transition in and out of assembly language also contributes to this conclusion.

On the other hand, FORTH programs tend to be highly modular, leading to a programming style that's a bit less procedural than typical C functions.

(I'm probably talking beyond my experience, which is minimal, and was quite a few years ago.) -- Jeff Grigg

Yes, you can do assembly in C, but when's the last time you saw someone do it?

^-- uh, yesterday?

I've seen it in the low-level primitives, where, to be honest, it's more of a syntactic convenience than something fundamental. That is, doing assembly in FORTH makes it so that you don't have to use a separate compiler/assembler and have separate source files.

In Forth, you can define a word that has a different effect on the stack depending on the parameters passed to it via the stack. e.g. If it's Tuesday, put an integer on the stack, otherwise, take one off. (This is allowed, but not encouraged.) There are lots of other languages where any such effect would always be classed as a bug, which would suggest that Forth users commonly encounter what might be called "stack effect bugs." It would settle this little discussion if we could say that C doesn't have this problem, but of course, in C, there is printf, which is the first thing you see when you read an introductory book about C, and which is an absolute black hole for exactly the same kind of bugs. Ain't the world crazy? -- Daniel Earwicker.

I read in the NASM documentation (Net Wide Assembler) that in the C calling convention, the caller allocates space on the stack for the parameters and the caller cleans it up as well. Thus, printf can mess itself up, but if it can find its return address on the stack, the program as a whole should recover. I'm not sure I can say the same for scanf: you can trick it into overwriting its return address.

Someone once said that the difference between a high-level language and a low-level language is that, in the lower level languages, you have to worry about the irrelevant. For example, in assembly languages, you have to handle the mechanics of register allocation and parameter-passing yourself. In C, you have to handle pointers. In C++, you still have to handle pointers. In a high-level language, such matters are handled for you.

Forth is a low-level language when you start, because it doesn't come with a large vocabulary of ready-made words for every application. But you can define words to make Forth run at as high a level as you want it to. You can transparently redefine any word Forth already comes with, and you can even hide the stack if you want to write your own parser (see Forth Macro). Because Forth doesn't impose a syntax of its own, this is cleaner than if you want to do something similar in C or C++ or Java. -- Edward Kiser (occasional Forth dabbler)

I think Forth is best described as a Meta Language or a Meta Programming language: it is a general-purpose language used to define Domain Specific Languages or application-specific languages. This is very powerful, but is also easily misused. -- Kris Johnson

Another word I've heard used in the attempt to describe this "both-high-low-level" aspect is "Proto Language." It "becomes" the language you need for the domain or application. -- Garry Hamilton

How often does such metaprogramming actually happen to the degree that a truly "higher level" language gets written on top of forth instead of simply composed of words that more or less use the existing control structures?

This depends on your experience level with Forth. If you're using Forth after a lifetime of C(++), you'll tend to write code that is structured very much like C. You'll run into constant problems doing this, what with massive stack imbalance bugs due to losing track of what is and isn't on the stack, etc. After some time with it, and if you haven't given up in disgust, you'll eventually come to realize that Forth encourages not so much abstraction, but rather conversation. The abstraction comes as a side-effect of conversing with your computer. Hence Forth's emphasis on words rather than functions.

For example, in C, if you want to write a program that prints a number in a variety of bases, you'd probably either have one function per base, or you'd pass the base as a parameter. In Forth, you simply "tell" it what base to print with. For example:

In C:

void print_inBase_(int aNumber, base b) { switch(b) { case B_DEC: printf("%d", aNumber); break; case B_HEX: printf("%X", aNumber); break; ...etc... } }

...

{ print_inBase_(0xDEADBEEF, B_DEC); print_inBase_(55, B_HEX); }

In Forth:

$DEADBEEF hex print 55 decimal print

Now, seeing how this works in Forth, some might realize, "Oh, hey, this rules!" and attempt to implement C-coding this way too. I don't recommend this, because dealing with thread-local storage is often quite painful. However, this makes perfect sense for objects to do, and in fact, is already done -- viva fseek(), ioctl(), and many others. So, assuming you create a "printer object" of sorts, you could write your C client code better, this way:

{ print(inDecimal(p), 0xDEADBEEF); print(inHex(p), 55); }

The key to making this work is that inDecimal()/inHex() obviously must return p itself, so that its print function can work! For this reason, it is not a coincidence that the default return value in Smalltalk is self.

BTW, since printing numbers was such a common task for Chuck when he implemented his code for NRAO, he provided a short-cut word to do the deed: dot (literally typed as ".").

$DEADBEEF hex . 55 decimal .

This results in a program that has a fair number of module-scoped variables, and if your Forth supports multitasking, user-variables as well (think thread-local storage). Interestingly, because of the conversational manner in which you program, saving and restoring these variables often doesn't occur, particularly if they're user-variables. Sometimes you need to, but it tends to be relatively rare.

For example, when programming graphics words for Forth, it is rare in Forth to see individual words take more than 2 or 3 parameters on the stack. So, to draw a box with some text in it, given some coordinates (L,T) (left, top of the box), we might see something like, oh, I dunno, this:

2variable text : ok S" OK " text 2! ; : cancel s" CANCEL" text 2! ; : top 2dup at over 64 + over horiz line ; ''Note that top, bottom, left, and right are "private" words,'' : bottom ( same as top but 12 pixels lower ) 12 + top 12 - ; ''in that after they're used in '''rect''', they may be safely'' : left 2dup at 2dup 12 + vert line ; ''redefined for other purposes later on in the program.'' : right ( same as left, 64 pixels over ) over 64 + over left 2drop ; ''See HyperStaticGlobalEnvironment'' : rect top bottom left right ; : text 2 + swap 10 + swap at text 2@ type ; : button rect text ;

So, we'd probably use it something like this:

( draw our dialog box here ) ... 100 200 green color ok button 300 200 red color cancel button

This style of programming meshes very well with Immediate Mode Guis as well. Some other folks will see obvious parallels with the Parameter Object pattern.

It seems to me that unlike with a stack-based VM that another language like Java or Python sits on, all significant Forth programs are written by folks who are not only comfortable with, but prefer Forth's lack of syntax and RPN conventions. It's like scheme and lisp macros: with the exception of the mini-language of LOOP, every lisp macro tends to keep strictly to sexp notation and even evaluation order, despite the power of macros to truly extend syntax.

Correct. It is possible to define infix-style languages in Forth, just like in Lisp. However, it is rarely performed, because again, there is no need to. Once you work with Forth for a while, you become familiar enough with the language to get by on your own without having the need for translators. A little while further, and you become fluent in it. Further still, it supplants your previous mode of thought in programming, and suddenly, everybody else suffers from Blub Paradox.

Not so much a negative criticism of forth (or lisp or scheme), but an observation that extensibility of a language tends to be used in very incremental ways, while those looking for radically new constructs tend to choose a different language entirely regardless of the expressive power of the macro suite.

Very interesting observation, indeed!

Possibly because all library code is still written in the "base" language

Well, at some point, something has to be written in the base language in order to provide higher-level services. If languages like Cee Language has taught us anything, it's that libraries can provide a large number of services formerly thought to only be renderable portably in the language itself. Cee Language demolished the ubiquity of Pascal Language and Pli Language for that reason. -- Samuel Falvo


Food for thought: Could Forth be translated "on the fly" to a more "conventional" looking form? Perhaps stack annotations can help with functions... Forth might be a good base for an Intentional Programming system then?

Hmm...translating Forth amounts to decompiling, which is in general difficult; what would you want the "conventional" form to be? I'm not sure I get your idea about a base for Intentional Programming, possibly because I don't know the subject well enough.

many Forths come with a decompiler built right in. :-) here is an example from GForth:

see ! Code !

( $402A4C ) mov dword ptr 4168E0 , ebx \ $89 $1D $E0 $68 $41 $0

( $402A52 ) mov edx , dword ptr 4 [esi] \ $8B $56 $4

( $402A55 ) mov eax , dword ptr [esi] \ $8B $6

( $402A57 ) add esi , # 8 \ $83 $C6 $8

( $402A5A ) mov dword ptr [eax] , edx \ $89 $10

( $402A5C ) add ebx , # 4 \ $83 $C3 $4

( $402A5F ) jmp dword ptr FC [ebx] \ $FF $63 $FC

( $402A62 ) mov esi , esi \ $89 $F6 end-code

ok

--- A better fit would be Forth used as the virtual machine for a another language. So "conventional" language compiles to Forth, Forth executes program.

Meta Programming is used in many Forth applications and libraries to better match the domain language. For example, the Forth Scientific Library, which uses Forth Macros to allow infix mathematical expressions, and more convenient use of vectors and matricies. There are also Forth Macro libraries that allow you to define state machines by simply laying out the tables of state transitions.


My first lesson in factoring functions came from FORTH. Because FORTH doesn't usually use many (or any) variables (accessing data mainly on the stack), large FORTH routines (called words) are extremely hard to read. Readable FORTH depends strongly on small, well named words. When you finally get the right mix of words that work together, there is an "Ah-HA" feeling that says "This is right!". Reading Martin Fowler's Refactoring book can bring that same kind of feeling. -- Jim Weirich

I think you meant to say, Forth functions don't use named parameters. Inside the body of a C function, named parameters act just like local variables. -- David Cary

Actually, Forth does support variables, like this:

VARIABLE BWAHAHA \ create an uninitialized variable called BWAHAHA, one cell in size 1000 BWAHAHA ! \ store 1000 in it (1000 in the current base is... 1000) BWAHAHA @ . \ --> prints 1000

For a while I developed an over-fondness for a word called LOCALS| which allows you to create local variables inside a word. LOCALS| is very bad for you because you can't easily factor a word which uses it.

HYPOT_SQ ( a b -- c ) \ define a word called HYPOT_SQ

LOCALS| b a | \ pops two parameters into local variables:
first pops b, then pops a

a a * b b * + \ calculate sum of squares 100 TO a \ you can store in your locals (here I'm just wasting CPU to prove it) ; \ semicolon automatically cleans up the locals

4 HYPOT_SQ . \ --> prints 25

However, there is this thing called VALUE which is like a cross between LOCALS| and VARIABLE. However, I should clarify that these VALUEs are not the least bit local, so their use is non-reentrant. The locals really are local.

VALUE a \ create a VALUE called a, initially 0

VALUE b \ create a VALUE called b, initially 0

HYPOT_SQ ( a b -- c )

TO b \ pop stack and store it in b TO a \ pop stack and store it in a a a * b b * + \ calculate sum of squares, which is left on stack ;

4 HYPOT_SQ . \ --> prints 25

a . \ --> prints 3 because a still contains it

Have you read about LOCALS| at www.complang.tuwien.ac.at ? It recommends syntax more like

HYPOT_SQ { a b -- c } \ define a word called HYPOT_SQ

\ and pops two parameters into local variables a a * b b * + \ calculate sum of squares 100 TO a \ you can store in your locals (here I'm just wasting CPU to prove it) ; \ semicolon automatically cleans up the locals

Of course for such a simple function I would probably just write

SQ ( a -- b ) DUP * ;

HYPOT_SQ ( a b -- c ) SQ SWAP SQ + ;

but I wanted to illustrate the options you have. If you want to write something moderately complicated in Forth like a Merge Sort then you will need to use a VARIABLE or VALUE or two; the stack will quickly grow too complicated to handle otherwise.

If a word uses variables or values you can factor it. -- Edward Kiser (much more experienced now)

Generally great advice, but, not necessarily always a good thing to be taken to extremes. You can write Spaghetti Code with factored Forth words as you can anything else. At some point, you'll find that you're factoring so much that your complexity grows out of control. As Chuck Moore states over and over again, never put more than 3 values on the stack at any one time in any given context (however, if there are 186291 values already on the stack, that's OK, you don't need to worry about those; your calling words will deal with those somehow). BTW, that patterns like Parameter Object exist suggests clearly that this principle applies broadly, not specifically just to Forth.


For my controversial statement of the day, I'll say... Some people say that FORTH is a "dead language." While it was once very popular in embedded systems, the availability of MS-DOS/Windows C/C++ development tools for cross-development to more powerful embedded platforms has caused a number of people to switch to C/C++. If SUN has its way, Java will take the field. (...and I'm inclined to think that they will.) -- Jeff Grigg

Forth Language As Development Tool describes how Forth as an extendable language grows until it models the structure of the target domain of the problem to be solved.

Frank Carver asked if Java is "too big" for Embedded Java memory limited implementations.

Anyone who says "Forth Is Dead", obviously doesn't know Forth.

Forth is not widely used, but its influence is bigger than its user base. To misquote Larry Wall, a real programmer can write Forth code in any language. I've written more Forth-like code in Java and C++ than I have in Forth! -- Edward Kiser (Note: my volume of Forth code has since caught up.)


The first language publicly available to program the original 128K Mac was Mac Forth http://www.macforth.com/ www.macforth.com, from CSI (Creative Solutions, Inc) in Rockville MD. (Mac development was then done on a Lisa.) Mac Forth was introduced in 2/84, before even the ring binder version of Inside Mac was available. (The one before the phonebook edition.) I wish I could remember the name of the implementor (great at forth, great as a hardware designer) to give him credit. CSI was sold some time ago, and moved to Western MD. I don't see them alive on the Web now, but may just have not looked hard enough. -- Jim Russell

From the Mac Forth Plus Manual: Mac Forth was created by Don Colburn and Dave Colburn. -- Felix Franz

Yes! Don Colburn was the name I couldn't recall. Very sharp guy.


An interesting? note: A guy named Jean-Paul Wippler is considering using Forth as a super glue language to bind Python Perl and Tcl together in a project called Minotaur. URL: www.equi4.com

is this wise?

Extremely. Forth is an ideal intermediary language, precisely because it's so agile. Otherwise, it wouldn't have been chosen for Open Firmware, which when you think about it, is a Forth system that must interface to a potentially wide variety of programming language environments.

In addition, Forth is now at the heart of the Tamarin implementation of Action Script. It is used as an introspectable meta-language, to aid in tracing a running Action Script program so that one can wisely choose which bits to compile Just In Time.


Is Forth still a good fit for modern commodity CPU architectures (Okay I'm talking Intel here), considering they tend to prefer registers to the stack? Is mapping the stack top to registers still the preferred optimization here? The question isn't whether Forth is obsolete, it obviously isn't, the question is whether it's really an ideal match for these particular architectures? The only other alternative seems to be assembly, but macro assembly is not something that lends itself to instant recompilation like Forth does, which allows the system to be kept largely free of "object code".

Nothing has changed on this subject for many, many years. Intel architectures are register-starved, so the lack of extreme register optimization found in most Forth implementations has much less effect on the first place than it does on a register-rich architecture, such as most RISC CPUs.

[This is silly - modern Inteloid CPUs have huge numbers of registers, hiding behind register re-naming. // I suspect register renaming won't much help an interpreter, though it may give a boost to JIT and the "dynamic superinstructions" in gforth. Interpreters typically have terrible behavior in deep pipelines anyway.]

It's not "silly", it is in fact correct, but ok, it's worth discussing. The question is not merely how many total registers exist behind the scenes, although obviously the larger register file plus renaming helped Pentium performance. Firstly, please note, although Intel has added every optimization it can, so that the Pentium isn't too far behind in the speed races, nonetheless it's never been a contender for fastest cpu at a given clock rate. Its architectural legacy is just too much baggage. This is just a reminder that it's not a subtle point of theory, there are some decades of benchmarks, too.

As to this particular issue, the externally visible architecture makes a difference, even if internally the code is translated to a completely different and more efficient form. Consider the extra machine instructions that need to be generated in order to e.g. recompute a constant, when there wasn't a spare register to hang onto the value for a while. Consider the extra data bandwidth used if the value is fetched rather than computed. Consider the register spills to/from the stack generated by the compiler when it runs out of registers. All of these things have a rather large cost, and in general it is quite impossible for the interior Pentium architecture to optimize them away.

So, as I said, the Pentium is register starved, and I stand by that.

Also, as has always been true, "inner loops" can be very easily optimized in Forth by creating new words defined in assembly.

Lastly, often the alternative is an even slower interpreted language.

State-of-the-art Forth Compilers from Forth Inc and MPE are as highly optimized as modern C compilers for the Intel architecture.

You are consistently misinterpreting my message as being anti-Forth, which was completely the opposite my intended points. The question was "is forth a good fit for modern CPUs?" And I answered that yes, it is, and why. You seem to be thinking I was saying "no, it's not".


See also Forth Wiki or make a fulltext search for Forth in this Wiki: c2.com


Please do not revert this page. Broken links have been fixed, obsolete links removed, and a new Forth URL added. (NOTE: as of November 2012 there are broken links and pages that were last updated in 2000, a dozen years ago. Isn't it about time the Forth community got hip to the fact that Forth Is Dead?)

Please, please -- some Forth addict clean up this page, eh? There are dead links and links to more dead links. Let's not let Wiki devolve into a repository of useless clutter, shall we?


See original on c2.com