Forth Language

Local Wiki Resources:

Getting Started With Forth:

StartingForth
LeoBrodie's classic Forth and programming tutorial. Now with modernized online versions.
http://www.sunterr.demon.co.uk/guide.htm
Guide to getting started with Win32Forth (includes download locations and introductory tutorials)
http://www.geocities.com/dolphinconsultant/myforth.html
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))
JsForth
Forth in JavaScript, running in a web browser window
http://wiki.forthfreak.net/index.cgi?ForthTutorials
online tutorials

Discussing Forth with others: IRC and other Forth-related wiki: (EditHint: move to ForthWiki ?)
news:comp.lang.forth
The UseNet newsgroup for Forth.
http://wiki.forthfreak.net/
Forthfreak - a Forth-specific wiki with an inventory of many Forth resources
SleeplessNightWiki
a wiki focused on QuartusForth, but with many general purpose pages as well
#forth@irc.freenode.net (openprojects is now freenode)
Introduction to irc at http://www.mirc.com/irc.html
http://wiki.enst.fr/bin/view/Picforth/
PicForth? - a wiki focused on PicForth?, 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? -- DavidCary
http://annexia.org/forth
JonesForth? - A concise, wonderfully well-commented Forth implementation in assembly. Reads like a novel.
http://www.forthwiki.com
Much more than just a wiki. FAQs, Forums, Articles, Blogs, Links and more.

Other Internet Resources:

http://www.forth.com/resources/evolution/index.html
A full history of Forth
http://www.taygeta.com/forth.html
The Taygeta archive of Forth resources
http://www.forth.com/
(Forth, Inc.) ForthInc was the first company to sell Forth products, and was founded by the inventors of Forth.
http://www.ultratechnology.com/
Recent work on hardware Forths, includes recent talks by Charles Moore
http://www.forth.org/fig.html
The Forth Interest Group
http://dec.bournemouth.ac.uk/forth/index.html
The Forth Research Page
http://www.zetetics.com/bj/papers/
Good papers on Forth implementation
http://forth.gsfc.nasa.gov/
Lists over 50 space-related uses of Forth
http://dmoz.org/Computers/Programming/Languages/Forth/
The OpenDirectoryProject listing for Forth
http://dir.yahoo.com/Computers_and_Internet/Programming_Languages/Forth/
The Yahoo listing for Forth
http://www.zforth.com/
The Forth Programming Webring
http://www.fig-uk.org/byof.htm
How to implement your own Forth
http://www.quartus.net/products/forth/
QuartusForth for the Palm - A whole development system self-contained on a Palm
http://www2.tunes.org/cgi-bin/TunesWiki?ForthOS
Forth as OS
http://ftp.uni-bremen.de/pub/mirrors/Taygeta-Archive/
UniversityOfBremen Ftp Site
http://home.vrweb.de/~stephan.becher/forth/
StrongForth?, a Forth dialect with strong type checking
http://rainbowforth.sourceforge.net/
An AJAX-y implementation of ColorForth 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 StackBasedLanguage based on PostfixNotation: 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 EmbeddedSystems:

The boot monitor on SunMicrosystems workstations includes a very useful ForthLanguage interpreter (OpenFirmware). HoursOfFun. (The "stars" sample code at ExampleForthCode 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 ThreadedInterpretiveLanguage. Among the variations used:

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


"HighLevelLanguage" ...

FORTH is a "HighLevelLanguage" 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.) -- JeffGrigg

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? -- DanielEarwicker.

I read in the NASM documentation (NetWideAssembler) 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 ForthMacro). 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. -- EdwardKiser (occasional Forth dabbler)

I think Forth is best described as a MetaLanguage or a MetaProgramming language: it is a general-purpose language used to define DomainSpecificLanguages or application-specific languages. This is very powerful, but is also easily misused. -- KrisJohnson

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

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
 : okS"OK  " text 2! ;
 : cancels" CANCEL" text 2! ;
 : top2dup 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
 : left2dup 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
 : recttop bottom left right ;
 : text2 + swap 10 + swap at text 2@ type ;
 : buttonrect text ;
So, we'd probably use it something like this:

 ( draw our dialog box here )
 ...
 100 200 green color ok button300 200 red color cancel button
This style of programming meshes very well with ImmediateModeGuis as well. Some other folks will see obvious parallels with the ParameterObject 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 BlubParadox.

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 CeeLanguage 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. CeeLanguage demolished the ubiquity of PascalLanguage and PliLanguage for that reason. -- SamuelFalvo?


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 IntentionalProgramming 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 IntentionalProgramming, possibly because I don't know the subject well enough.

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.

MetaProgramming is used in many Forth applications and libraries to better match the domain language. For example, the Forth Scientific Library, which uses ForthMacros to allow infix mathematical expressions, and more convenient use of vectors and matricies. There are also ForthMacro 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. -- JimWeirich

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. -- DavidCary

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
  1. TO a\ you can store in your locals (here I'm just wasting CPU to prove it)
;\ semicolon automatically cleans up the locals

3 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.

 0 VALUE a \ create a VALUE called a, initially 0
 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 ;

3 4 HYPOT_SQ . \ --> prints 25 a . \ --> prints 3 because a still contains it
Have you read about LOCALS| at http://www.complang.tuwien.ac.at/forth/faq/faq-general-4.html#ss4.4? 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
  1. 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 MergeSort 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. -- EdwardKiser (much more experienced now)

Generally great advice, but, not necessarily always a good thing to be taken to extremes. You can write SpaghettiCode 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 ChuckMoore 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 ParameterObject 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.) -- JeffGrigg

ForthLanguageAsDevelopmentTool? describes how Forth as an extendable language grows until it models the structure of the target domain of the problem to be solved.

FrankCarver asked if Java is "too big" for EmbeddedJava memory limited implementations.

-- AnonymousDonor-s

Anyone who says "ForthIsDead", obviously doesn't know Forth. -- BillZimmerly

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! -- EdwardKiser (Note: my volume of Forth code has since caught up.)


The first language publicly available to program the original 128K Mac was MacForth? [http://www.macforth.com/], from CSI (Creative Solutions, Inc) in Rockville MD. (Mac development was then done on a Lisa.) MacForth? 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. -- JimRussell

From the MacForth? Plus Manual: MacForth? was created by Don Colburn and Dave Colburn. -- FelixFranz 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: http://www.equi4.com/minotaur/minotaur.html

is this wise?

Extremely. Forth is an ideal intermediary language, precisely because it's so agile. Otherwise, it wouldn't have been chosen for OpenFirmware, 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 ActionScript. It is used as an introspectable meta-language, to aid in tracing a running ActionScript program so that one can wisely choose which bits to compile JustInTime.


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.

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 ForthCompilers from ForthInc 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 ForthWiki or make a fulltext search for Forth in this Wiki: http://c2.com/cgi/fullSearch?search=Forth


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 ForthIsDead?)

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?


CategoryProgrammingLanguage, CategoryForth


EditText of this page (last edited February 9, 2013) or FindPage with title or text search