Forth: The Hacker’s Language

Let’s start right off with a controversial claim: Forth is the hacker’s programming language. Coding in Forth is a little bit like writing assembly language, interactively, for a strange CPU architecture that doesn’t exist. Forth is a virtual machine, an interpreted command-line, and a compiler all in one. And all of this is simple enough that it’s easily capable of running in a few kilobytes of memory. When your Forth code is right, it reads just like a natural-language sentence but getting there involves a bit of puzzle solving.

From Thinking FORTH (PDF)

Forth is what you’d get if Python slept with Assembly Language: interactive, expressive, and without syntactical baggage, but still very close to the metal. Is it a high-level language or a low-level language? Yes! Or rather, it’s the shortest path from one to the other. You can, and must, peek and poke directly into memory in Forth, but you can also build up a body of higher-level code fast enough that you won’t mind. In my opinion, this combination of live coding and proximity to the hardware makes Forth great for exploring new microcontrollers or working them into your projects. It’s a fun language to write a hardware abstraction layer in.

But Forth is also like a high-wire act; if C gives you enough rope to hang yourself, Forth is a flamethrower crawling with cobras. There is no type checking, no scope, and no separation of data and code. You can do horrible things like redefine 2 as a function that will return seven, and forever after your math won’t work. (But why would you?) You can easily jump off into bad sections of memory and crash the system. You will develop a good mental model of what data is on the stack at any given time, or you will suffer. If you want a compiler to worry about code safety for you, go see Rust, Ada, or Java. You will not find it here. Forth is about simplicity and flexibility.

Being simple and flexible also means being extensible. Almost nothing is included with most Forth systems by default. If you like object-oriented style programming, for instance, Gforth comes with no fewer than three different object frameworks, and you get to choose whichever suits your problem or your style best. You can modify the Forth compiler or interpreter itself, so if you want type checking, you can add it. Some Forth implementations are written with just twenty or thirty functions in native assembly or C, and the rest is bootstrapped in Forth. Faster Forths are implemented entirely in assembly language, with some compile-time optimizations that make it run about as fast as anything else, even though it’s compiled as you type, on the target microcontroller itself.

Forth is probably not the language you want to learn if you are designing an enterprise banking backend. On the other hand, a string of blinky LEDs running a physics simulation isn’t an “enterprise” anything. Forth is a hacker’s language, in both the laudatory and the pejorative senses. I’m not sure that it’s going to help you get “real work” done at all, and you engineer types might want to walk away now. But if you want to tweak at the language itself, or use it to push your hardware around, or just play, Forth is fantastic. The hacker in me thinks that’s a lot of fun, and it’s a great match for smaller microcontroller projects.

Forth Crash Course: Theory Section

Forth is the simplest language after assembly language. Forth is procedural in the extreme — a Forth program is really just a chain of subroutines, called “words” in the Forth jargon. There’s no syntax, and all words are separated by a space and are parsed left to right. With a few exceptions for compiling, all words run right now so the Forth interpreter doesn’t have to look ahead to the next word. run this code! is valid Forth if you’ve already defined the words run, this, and code! and it calls each of the three words in the order that you’d expect.

Simplicity and Reverse Polish Notation

The corollary of this simple setup is that Forth uses the so-called Reverse Polish Notation (RPN). If the Forth interpreter is going to execute the + word right now, it has to have the two numbers that are going to get added already on the stack. Otherwise, it would have to wait for the next number to come along before it could finish the addition. Read that again, and let it sink in. It’s different from what you’re used to, and it’s important.

crazyAny other ordering or syntax is unnecessarily complicated. The way that you think of as “natural” to write down math is crazy, in the sense that the look-ahead nature of the + operator requires either parentheses or an “order of operations” to be unambiguous. Look at 2 + 3 * 4. There is nothing natural about getting 14 here at all — it’s the result of a convoluted syntax with implicit rules. You have to read the whole “sentence” first, find the *, remember that it has priority over +, evaluate it first, and then go back to the addition to finish up, even though + is the second word in the sentence. A computer doesn’t want to know about “order of operations”, it just wants to add two numbers, preferably ones that are already sitting in ALU registers. Don’t believe me? Read the machine code.

Forth, and RPN, write this as 2 3 4 * + or 3 4 * 2 +. Either way, the operator works on whatever numbers are already available. If you don’t think of this as being “reverse” or “polish” or even a “notation”, you’ll be on the right track. You’re simply writing things down in the order in which they should be executed. (How crazy is that!?!)

I like to think of RPN as the computing equivalent of mis en place; before you start cooking, you get all your ingredients lined up. This is the way Forth code works: get.broccoli chop.broccoli get.beef slice.beef get.oyster-sauce stir.fry Some elements are naturally interchangeable — you could get and slice the beef before the broccoli — but the overall order is important to the procedure, and you really don’t want to be going back to slice the broccoli while the beef is in the wok. But this is exactly what you’re doing when you insist on writing 3 + 4 instead of 3 4 +.

Compiling and Running

New words are defined and compiled with a : to enter compilation mode and a ; to exit. Compilation, such as it is, takes place immediately. Under the hood, the Forth interpreter is looking up each word that you use in the definition and simply stringing them together. One exception to this rule is the function name itself, as you’ll see now.

Starting FORTH

Compile your first Forth word: : seven 3 4 + ;. It’s not very useful, but it creates a word called seven that will put a 3 and a 4 on the stack and then run the addition word. The “result” is that whatever you had on the stack before, you’ll have a 7 on top of it now. An optimizing Forth compiler will just push a 7 onto the stack.

All programming is about breaking complicated tasks down into reasonable-sized chunks. What constitutes “reasonable” depends a bit on the language, a bit on the programmer’s own style, and a bit on the cultural zeitgeist. Executing a word in Forth requires a lot less overhead than a function call in C, and following long code logics can get convoluted even for experienced Forthers, so the definition of Forth words tend to be extremely short, typically one-liners including comments. You’ll be compiling quite often.

The Stack

The heart and soul of Forth is the data stack, henceforth “the stack”. Forth is a stack-based language, and until you’ve coded in Forth for a while, you can’t appreciate what this really means and how thoughts about the stack come to dominate your coding life. Forth words don’t take arguments or return values, instead they operate on whatever data is on the stack when they’re called.

Starting FORTH

The stack is the best and worst part of Forth. When your stack contents line up right with the words that operate on them, the result is code of a beauty and efficiency that can’t be beat. When they misalign, you find yourself wondering if the object-oriented folks aren’t right, and that coupling data with methods might be a good idea after all.

The gimmick in Forth programming is figuring out what’s needed on the stack by one word, and making sure that the word used just beforehand leaves that on the stack. In this sense, the Forth programmer defines words, but needs to think in phrases, where the contents of the stack start out empty and end that way again. This is like the way that C uses the stack within a function scope, keeping the local variables only until it’s done with the function, and then overwriting them.

As a concrete example of this chaining, imagine a word, gpio-set that sets a GPIO pin high. It will probably need both a port and a pin number to get the job done. A particularly Forthy way to implement this is to define a word for each pin on the part that you’re going to use: : PA3 PORTA 3 ; Then you can light the LED on pin A3 with PA3 gpio-set. In C, you’d first define a structure that includes a port and a pin number, then define gpio-set to take a structure of that type. In Forth, this is implicit: you make sure that the pin words push a port and pin number onto the stack, and then that pin-handling words expect them. It’s not safe, but it’s simple.

Stack Juggling

Swap-swap, the Forth Mascot, from Starting FORTH
Swap-swap, the Forth Mascot, from Starting FORTH

The absolutely worst part of Forth is stack manipulations. People usually start learning Forth by learning about the stack manipulations, and indeed they are important, but they’re trivial. Words like swap, drop, and dup let you move items around on the stack, but too many “stack juggling” manipulations in a given word is probably a sign of bad Forth code, rather than good. You’ll use these words for sure, but that’s not where the bodies are buried.

Rather, the stack is where the absolute minimal amount of data wants to sit between processing steps. The number of items needs to be small enough to avoid running out of finite stack space, of course. But a second reason is that it’s simply hard to keep too many stack items straight in your mind. As you get used to Forth, the amount of stack that you can internalize might go up from three items to five or seven, but you’re going to get confused if you let the stack grow unpruned for long.

So Forth is a disaster. It’s a language where you have to manage the stack yourself, and the only hope of not getting caught in a tangled web of endless stack juggling is to keep things as simple as possible. Forth proponents would claim that this is also its greatest virtue — there’s always pressure to keep things simple and straightforward because doing anything else will embed un-figure-outable bugs so deep into your code that you’ll go mad. I don’t know if it’s Stockholm syndrome, whether I’m a minimalist at heart, or whether I like the challenge, but this is actually one of the reasons that Forth is so neat.

Other programming languages allow you to juggle tens of variables because the compiler keeps track of different scopes for you, keeping track of how deep each (local) variable is on the stack. Forth doesn’t. And that means that you need to think about the order in which things run. Forth forces you to internalize a bit of optimization that an ideal compiler would do for you. This can end up in very tight code, or in headaches. It depends on the programmer and the problem.

In my experience, simple syntax, computer-friendly ordering, and the resulting emphasis on transparency and simplicity make it actually surprisingly easy to get stuff right in Forth.

The Sweet Spot

But enough philosophical crap about Forth. If you want that, you can read it elsewhere in copious quantities. (See the glossary below.) There are three reasons that Forth more interesting to the hardware hacker right now than ever before. The first reason is that Forth was developed for the computers of the late 1970s and early 1980s, and this level of power and sophistication is just about what you find in every $3 microcontroller on the market right now. The other two reasons are intertwined, but revolve around one particular Forth implementation.


There are a million Forths, and each one is a special snowflake. We’ve covered Forth for the AVRs, Forth on ARMs, and most recently Forth on an ESP8266. The joke goes that if you’ve seen one Forth implementation, you’ve seen one Forth implementation. But I think that’s too cynical — Forth is as much a way of thinking about the computer programming problem as it is a particular implementation. Once you learn one, you’ll be on good footing to learn any other.

Anyway, a few years ago, a physics graduate student [Matthias Koch] wrote a Forth for the MSP430 because he needed a microcontroller to collect analog data for an experiment. That’s “Mecrisp”. Later on, he needed more speed and re-wrote it for the ARM Cortex M family of chips, and we got “Mecrisp-Stellaris“.

And that’s where things got awesome. [Jean-Claude Wippler], the “J” in JeeLabs, decided that he was going to implement his new system of distributed electrical and environmental sensors in Forth, at least under the hood. To do this, he needed a hardware abstraction layer. The combination of Mecrisp-Stellaris with the JeeLabs libraries is a tremendous Forth ecosystem for a whole bunch of ARM microcontrollers, and it has all been developed within the last two years by a small core of thoughtful hackers. Combining the two provides a very pleasant Forth microcontroller hacking experience, like a weird interactive Arduino.

Your Homework

So if you want to follow along down a very strange rabbit hole, learn a bit about the real hacker’s programming language, or just fool around, stay tuned. In a couple of weeks, I’ll publish a hands-on guide to getting started with Mecrisp-Stellaris on the STM32 family ARM chips.

These are the droids you're looking for.
These are the droids you’re looking for.

A good minimum Mecrisp-Stellaris development environment is going to consist of a cheap STM32F103 development board, a ST-Link v2 (or better) programmer for it, and a USB-TTL serial adapter. Chances are good that you’ve got at least the latter kicking around already. If so, you could be set up with the rest for around $10, €10, or £10 depending on where you live. “STM32F103” and “ST-link” should get you set up on eBay.

So order some parts right now. While you’re waiting for delivery, work through this very good online tutorial. Run through that, and you’ll be set for next time.

If you want to go further, you can download a Forth for your desktop computer and start working through some other introductions.  Brodie’s “Starting FORTH” is the canonical Forth introduction, but it’s a bit dated (and feel free to skip Chapter 3 on disk access). If you prefer brevity over humor, check out J.V. Noble’s Beginner’s Guide or the Gforth tutorial.

All images from Starting FORTH used by permission from FORTH, Inc. The originals are black and white, rather than Hackaday dark charcoal and yellow, naturally.

210 thoughts on “Forth: The Hacker’s Language

  1. A nice overview.
    I’ve used the language since 1980 for work and hobby projects. It’s my daily tool.
    I use my own compiler (I know, I know, but I have been doing this a long time) but I’d recommend the VFX compiler. It’s not cheap, but it generates great code.
    No need to write interrupt routines in assembly, the Forth is good enough.
    And check out comp.lang.forth for discussions.

  2. I’ve been partial to RPN since cutting my teeth on an HP RPN calculator but have never gotten into forth. This article makes me want to try.

    One small correction: 2 + 3 * 4 should evaluate to 14, not 24.

    1. Not in Occam and a few other languages.
      For a programmer switching between different languages different precedence rules can be a PITA and cause bugs that are nearly impossible to spot. OTOH switching between a language with precedence and another without can also cause problems.

      Solution: always use parentheses.

  3. I worked for a firm in the mid-70 to mid-80s that had PL1 as the
    complied high level language on 8080 and Z80 micros.
    It was compiled to a pseudo-code that I now realize was forth-based.
    The operating system for printer [daisy wheel], keyboard, display [plasma],
    floppy disk I/O and Interpreter all fit in 6K of ROM.

  4. Bad timing for eBay Chinese orders. Most of them are shut down for the next 10 days (or more) and the shipping back log after the Spring Festival will slow things down for another 10.

    1. And AliExpress. But that’s just as well, because the reliability of AliExpress vendors has become 𝘦𝘹𝘵𝘳𝘦𝘮𝘦𝘭𝘺 poor in recent months. I used to buy tons of stuff from that site, but have completely given up on it. Way too much aggravation.

      1. I noticed the same about AliExpress vendors lately, but I assumed that it was just bad luck with the last orders. In 2015 I never opened a dispute, but for all of the last 3 orders of 2016 a dispute was necessary.

        Does anybody know any reasons that could have changed the vendor’s behavior, please?

      2. Use Banggood or Taobao. I don’t use Aliexpress. If you need something bigger and are in the US, I have an agent in Shenzhen/Guangzhou and might be able to get on-site inspection.

      3. Me too. Last two orders never arrived and the one previous to those took over two months. I only buy from the east when it’s likely to, um, go *boom* during testing anyway. I usually go as local as possible.

    2. “Bad timing for eBay Chinese orders..Spring Festival” My bad! Well, the article will still be there when you get the parts. Or just for you, I’ll write extra slowly. :)

      Or you could patronize one of your local re-sellers for a couple bucks more. I do that more than I’d like to admit, b/c shipping within Germany is like 1-2 days, and shipping from China is like 1-2 months…

  5. So no Forth for Arduino? :)

    I’m tempted if you can show that Forth is much faster, especially for I/O, than other common microcontroller languages.
    Otherwise I’ll stick to assembly for fast tasks, and Arduino C (or whatever it is called) for slow ones.

      1. Nothing seems to come anywhere close to Forth in development speed. Also, it’s easy to mix assembly-language routines in with Forth for the time-critical portions; and as they say, you can get 90 or 95% of max performance with only a tiny portion of the code in assembly, provided it’s the right portion. If your Forth does not have an onboard assembler, it’s easy to add one. I wrote mine in an evening; and since it’s Forth, macro capability is automatic. You can even use INLINE to jump into assembly language in the middle of a high-level Forth definition and then and END-INLINE to get back to Forth before finishing the definition.

        In assembly-language-only applications have benefited from forming Forth-like structure macros too. They improved my assembly-language productivity and enjoyment. In most cases, the macros assemble exactly the same thing I would have done if I had to write it all out by hand, so there’s no penalty in either performance or memory taken.

        The fastest executing though is on stack processors where the machine language basically _is_ Forth. In that case, it screams performance, with more than one Forth primitive per clock cycle, ie more Forth MIPS than MHz.

        1. Over the last couple of months I have heard about 3 or 4 different independent implementations of Forth Stack machines from people I know. They were done for performance and can be combined with C ( or are written in C ) and assembly. The big help is the well prepared structure that you have to follow – which saves design time as well. But Forth or similar is not for everybody.

    1. I don’t know which Arduino you mean. For the AVR ones, see AmForth. For the Atmel SAM ARM ones, maybe not / dunno. I toyed with doing the next (practical) article on the Arduino UNO, but AmForth is a bit clunkier, and the cheap chinese STM32F103 boards are really amazing bang/buck. You should be using them anyway. :)

      On speed: I’m not sure how it works with GCC -Os vs Mecrsip-Stellaris. Function calls are slower in C than Forth, because there’s a lot of necessary context switching. But smart compilers optimize a lot of that out, taking the advantage away. Matthias’ latest Mecrisp versions use register allocation, which keep most of the stack manipulations in the CPU’s registers, so it’s a pretty fast Forth. I haven’t benchmarked anything. Speed has not been a problem, and I’m used to C.

      Suggest a couple quick and dirty benchmarks?

      There’s a tremendous difference in speed between running Forth code live (interpreted) and compiled (as words). This is worth knowing if you’re trying to debug something time-critical.

      1. Thanks to all people that replied, I have read through your comments with interest. Arduino is something that everyone has, so it would be easy to compare performances of stock Arduino C vs Forth. I will look at AmForth tomorrow. RPN does not sit well with me since I’m used to other languages, but it might be easier for the processor itself, as many pointed out. That itself should translate to more speed.

    2. There are several versions of Forth for Arduino Elliot mentioned AMFORTH (general purpose AVR Forth.)
      There is also and
      “Forth” is a pretty good search term for the Arduino forums…
      (It does turn out that implementing a “typical” interactive Forth with user-definable words has some “special issues” on a flash-based microcontroller. The AMForth implementation is basically incompatible with the Arduino Bootloader, for instance.)

      1. Thanks — I need to take a tour of the AVR Forths some day.

        I actually really like the way Mecrisp handles flash vs RAM, though. You have plenty of space in RAM to play around, and when you get something you like, burn it to flash and reset: all the mistakes left over in RAM get cleared, and the functions that worked remain.

        It provides a quasi-clean-slate that makes developing and testing code incrementally very pleasant. Feature, not a bug. :)

    3. I got Forth up and running on an arduino, setup script available on the first search hit for forthduino.
      Since then I’ve used SwiftForth and I can’t recommend it enough, it’s paid but the cross-compiling and debugging makes everything much easier.

  6. Forth was a necessary step in the evolution of compilers, as was pascal.

    However, these languages are no longer popular since computers that can run GNU gcc cross-compiler toolchains are now ubiquitous. i.e. you no longer have to manually bootstrap an environment to get a new piece of hardware to run the native compilers and OS.

    After a few decades of countless projects, I have found that if C can’t do something (usually a vendor’s commercial compiler that isn’t even ANSII 89 compliant), than it’s probably back to linking in assembly sections. Also, any architecture that can’t run gcc C/C++ seems to go EOL relatively quickly days…

    Most scripting languages like Python heavily rely on SWiG wrappers for the shared C/C++ lib objects.

    Lisp was written by Aliens for Aliens, if someone recommends this… check for brace shaped antennas… seriously…

    1. Most Forths have an assembler vocabulary and you can use the conditionals like IF ELSE THEN, and Do While and all that within the assembler. It makes for pretty good assembly after you get use to RPN assembly, which is more natural anyway. And you can switch radix at will and dump that 0x notation.

      1. “Necessary” and “popular” have nothing to do with it! :)

        As you say, you can always drop down to assembler in C / Forth when needed. But I can count on one hand the times I’ve done so outside of an ISR.

        Fun in Forth: interactive machine language. You can just push the opcodes into RAM and run them. here $8381 , execute pushes the current RAM pointer onto the stack, compiles two opcodes into RAM — HALT and RET on the STM8S in this example — and runs them. From the “command line” running on the microcontroller. Now that’s fun. (For odd values of “fun”.)

    1. LOL. So true.

      I wrote this piece with a bit of self-loathing. Some Forth folks are way too enthusiastic and fail to see its flaws. Searching about Forth online will bring up a lot of that.

      But when you go looking for projects or example working code, you come up empty. I think that’s a shame. What I think is awesome about the Mecrisp / Jeelabs setup is that it’s fun to get stuff done. I promise the next article will be all application, and no proselytizing.

      1. one of the best Forth programs I’ve used is Voyager, the desktop planetarium for the Mac.

        When I first started using Voyager on my Mac plus, I saw the “Uses fig Forth” in the about dialog.

        looking closer with resedit at the code fork I found the dictionary, some of the words were in assembler, the rest in Forth.

        Has anyone else ever heard of the Novix chips and other processors that directly execute Forth?

      2. [quote] “But when you go looking for projects or example working code, you come up empty. I think that’s a shame.”[/quote]

        I’m sure it’s that the work projects are proprietary, and the I/O hardware is individual to the project, unlike PCs which are mostly compatible with each other.

        My first big Forth project was automated production test equipment, in 1990-91, shown at . The equipment was on STD Bus, and we designed several of our own custom boards, for power supplies, loads, switching matrix, DVM, and signal generators, all controlled by the SBC. It worked out very nicely. This was the third ATE setup I had done. Previously I had used “rack-and-stack” IEEE-488 instrumentation, and the last one was controlled by an HP computer running HP’s Rocky Mountain BASIC.

        A couple of years later I designed, built, and programmed a gizmo to measure and record track sprinters’ acceleration through different segments of a 100-yard dash (for training), again done in Forth.

        Since then, I’ve done a long list of Forth projects on my home-made workbench computer, but always smaller ones to do things like try out new ICs or displays I was considering using in one of our aircraft communications products, control experiments, take data and print or display it, generate signals, program microcontrollers, and in a pinch, substitute for other lab equipment that I didn’t have. Most of the Forth code would be of little use to others, but I do have snippets here and there among the assembly snippets on my extensive hobby website, .

  7. You can do horrible things like redefine 2 as a function that will return seven, and forever after your math won’t work.

    A problem not unique to FORTH. I once accidentally did this in FORTRAN II on a PDP-8. FORTRAN passes things by reference (that is, it passes a pointer to the value); modifying a parameter changed the location in which the compiler had stashed the constant.

    I’ve long found FORTH very useful for diagnostics. For example, I once did a FORTH that lived entirely within the cache of NV5+, a VAX processor that is mostly pin-compatible with the 21064 Alpha. The NV5+ (and the 21064, for that matter) boots by loading a serial EPROM into the cache and jumping to it; my FORTH resided in that EPROM, using the EPROM data lines after boot as a bit-banged serial port. Thus, with the NV5+, a serial EPROM, and an RS-232 transceiver, I had a little FORTH machine.

    In the system, I was trying to use support chips for the 21064 (APECS) to provide memory and a PCI bus for the NV5+. The FORTH living in the cache allowed me to play with the interface before knowing whether it would work; not surprisingly, the APECS documentation didn’t address issues that might arise when using a VAX processor instead of an Alpha; it was never intended for such use.

    When accessing main memory, the cache-based FORTH would figure out which cache line was going to get clobbered and squirrel away a copy before doing the access. Restoring the line from the saved copy repaired the damage.

    It turned out there were some fundamental disagreements between APECS and NV5+; some things that were configurable on 21064 were fixed on NV5+ and APECS had chosen the other options. Because of this small, cache-based FORTH, I was able to figure out a workaround and, for one brief shining moment, there existed a VAXstation 200/4 100, complete with PCI bus. ‘Course, it was only ever able to run FORTH, but I was able to run out of main memory and use COM 1 as the console, which meant I was, in fact, talking to APECS.

  8. I used Forth on an OG Macintosh in ’84-86, because it was one of the few dev environments out there that (a) didn’t require licensing if you wanted to sell something, (b) actually ran on a Mac (the official toolchain required a Lisa), (c) was under $100, and (d) didn’t depend on updates that were never coming during those days of rapid changes to the OS — you could just push the new routines on the stack and they worked. On the Mac it could also be used as an assembler/disassembler: You could output the machine code of a word you’d created, which made it possible to code up new system calls on the Mac Turbo Pascal (which was orphaned shortly after release, no OS 5 for you!).

    Forth is also the basis for PostScript (and thus PDF), which made it a good stepping stone for figuring out those graphics calls. I had fun running fractals on an OG LaserWriter that could take an hour to print.

        1. The stack operators and their names. Just about everything really. Warnock just spelled them out and made everything floating point. Postscript is a great accomplishment. I just nev3er understood why he denied knowing Anything about Forth. The Forth Interest Group was right there. Mountainview Press was right there, Atari was right there using Forth for Video games, National was putting it in uP ROMs, the FIG newsletter was everywhere and it was in all the industry and hobby publications. What can I say? It was hard to believe him.

  9. My favorite part of this article is that there is no break in it. It reminds me of HAD back when there was one hack per day and it was worth reading the summary. Keep it up Elliot.

  10. I feel like there used to be a reason for Forth but that time has come and gone. One could argue that Forth is the concept of a virtual machine and in that way lives on but beyond that it seems like a fairly dead language. If you really want to learn about a microcontroller then you should learn the instruction set for that architecture.

    1. I wasn’t interested in Forth myself until I found the relationship between it and my HP48SX. I recently setup FlashForth on a PIC18F45K20 and I’m starting to like it over the Ardiono as its interactive, no need to compile and send.

      1. That is true in a lot of ways. Once PC’s go so fast that you don’t have to wait for assembly or compilation, some of the advantages are gone. But you still really need a bunch of tools like GCC, GDB, and Eclipse and a very fast box to make the response time as good as interactively using Forth natively on a 1MHz micro to figure out the details of a new interface.

        1. Not so much the compile time but the time to send the code over to the micro. A few hundred lines of code compile almost instantly even on my little netbook but then waiting for it to download to the PIC or Arduino/Atmel you wait for it to download, flash, verify, etc.
          Or the time to take to edit the code to put in a debug routine before you compile and download.

          1. So how does that work? Is it storing your new Forth words in RAM, or writing to it’s own flash, or what? Since RAM is something MCUs don’t usually have much of.

          2. Yes, stores in the flash. It seems to work well for my ADD kids, rather than doing the wait a minute while I edit this code in the tiny arduino editor and wait for it to download, instead its immediate when you make a change.

          3. It has to save to flash to be worth anything. The interpreter might run from flash or RAM depending on the advantages. The party that navigates through the pointers that make up the code, the inner interpreter, is about 20 instructions long in a 65C02 and on an ARM it cam be 2 instructions provided you have the ARM instruction set with conditional execution of all instructions. In that case, one might as well stick the 2 instructions on the end of every definition to avoid disturbing the pipeline.

            Anyway, the interpreter and stacks (There is a data stack and a return/loop stack and in some cases an additional floating point stack and other special stacks.) don’t take much room. Analysis of complex code shows that stack depths very rarely exceed 16 entries. It isn’t like C, where stack space is allocated for everything in your function, including arrays. So stack and interpreter and space for variables and buffers is not very much. On a 6502 (I use that since it is close enough to AVR and a lot of work was done on 6502) the stacks and a bunch of variables and all that fit in an available portion of the 256 byte zero page on an Apple II. The AIM-65 from Rockwell shipped with 1K of RAM and a Forth ROM. Expandable to 4K and was used for a lot of industrial control.

            One big difference with C (unless specially modified Forth) is string handling. Forth uses counted strings. They start with a length. C was created on mainframes with tape archives. In fact, the .tar in Linux stands for Tape ARchive. So C was designed to deal with streams of data of unknown length – I should say the C lib. C doesn’t care. With the Forth method you can allocate space because you know how much you need, and there are no forbidden values for string data, like EOF. The string input and output is Pretty strange if you are used to C. On the other hand, C string I/O sucks if you used any other language. Modern Forths almost always have string handling extensions that match the C per-processor.

            If you see the # symbol in Forth, it is called “sharp”, like in music, when written conversationally. ! is “store” and @ is “fetch”. @ is replace the top of the stack with the contents of the address it was pointing to. ! is store the second item on the stack using the top of the item on top as the address, and throw them away.

            When you want to change radix or base, you just do it. And you print the top of stack (TOS) with a period. The prompt is “OK” when whatever you type can be interpreted. I’ll ignore it.

            10 HEX . A DECIMAL . A 16

            Make a new word to set octal

            : OCTAL 8 BASE ! ;

            A good version would save the current radix, set decimal perhaps so you can use a number for the base that makes sense to you, then restores the current base. Well, I did not intend to write so much. I suspect Elliott intends to cover some of this in better form. It has been a very long time. I think I need more Forth.

            : MoreForth 100 0 DO CR .” More Cowbell!” LOOP ;

          1. I have an 8 core AMD with a hybrid HD and it builds kernels in 53 seconds — with a -j 16 option. On application code it is not noticeable, especially after the first compile and stuff is in cache.

          2. First compilation of code isn’t even the use case though, incremental updates is the use case, and if that takes longer than it takes to press a button and move your hand back from the keyboard, blame your IDE not the language.

            When I’m writing C, there is no way I’m writing more than a few dozen lines of code between compilation steps; and it would be unlikely to have more than 2 or 3 files changed.

            OTOH, transmitting compiled binaries to a micro takes significant time regardless of the tools used.

    2. Forth was create by Chuck Moore to control the Kitt Peak radiotelescope, those big dishes on railroad cars, back in the late 60’s. It is still very relevant for robotics. The reason is that you can test every operation as you add it to your code. That can be *very* important if your robot weighs many tons. You can’t do that as easily with either assembler or C.

      Very little of a forth system need or should be written in assembler. Most of it is written in forth. So ports are relatively low cost. in fact, so low that Chuck Moore is notorious for starting from scratch on every system. Because the primitives are so simple, an experienced person can port forth about as fast as they can read the MCU documentation.

      Yes, people have written almost everything you can imagine in forth. In many cases because they could. It is not a replacement for FORTRAN, COBOL or C, all of which were written to solve very specific classes of problems as was forth. Forth will be obsolete when robotics becomes obsolete.

      Great article Elliot. Thanks for sparing me my usual plug for Mecrisp ;-) I keep hoping for a Mecrisp port to the Arduino, but first I’d like Matthias to finally finish his PhD. I’ll have to look at FlashForth. I’d not heard of it. Yeah, I know. I should do a Mecrisp port myself, but I’ve got other tasks.

        1. I took a class at Forth, Inc in 1977 from Liz Rather. Never heard anything about looms. Chuck did implement something forth-ish in Fortran before Kitt Peak. One of his motivations was a portable toolkit he could carry from job to job.

        2. I took a class in Forth from Liz Rather at Forth, Inc. in 1977. Never heard anything about looms. Chuck did have a forth-ish implementation in Fortran. His motivation was to have a portable toolkit of tools he could carry with him from job to job. That risked copyright problem but he managed. (Yes, your work for a company is copyrighted by them so taking it elsewhere is a problem. Some exceptions for consultants, etc.)

          1. This was a tenacious problem when it came to building Forth engine hardware, which he worked on several times. There was a trail of old associates and employers who all wanted a piece of the action. He wrote complete CAD and simulation suites in a new Forth he designed for that purpose. It was cool stuff, with objects that knew their impedance and other properties. Signal prorogation down traces could be watched in slow motion, etc. Very cool.

      1. Some of the register allocation and inlining/tail-call cleverness going on in Mecrisp makes it definitely worth writing in assembly. I’d put my money on Mecrisp vs. any bootstrapped Forth. I doubt it’s orders of magnitude, though.

        What really blows my mind is James Bowman’s Forth machine in an FPGA (and Mecrisp-Ice). The Forth _is_ the machine code because the machine matches the Forth virtual machine. There is no intermediate layer. Whoah. (I presume Chuck Moore also lives in this world.)

        I _do_ love the portability aspect. I’m playing with three different chips at the moment, and not having to switch between APIs across them is actually very refreshing. How the heck is it that Forth is more portable than C?!?!

        I’d rather a fully functional ESP8266 / ESP32 port than to any AVR. I need to look at punyforth again.

        Everything you said ++.

        1. The newest interest of Chuck Moore (the inventor of Forth who turns 79 this year, 2017) seems to be GreenArrays where he has 144 stack processors on a single IC, for massively parallel embedded applications. Each of the processors on the IC runs Forth instructions in as little as 1.4ns, putting equivalent peak performance at 100GIPS, or 100,000,000,000 Forth instructions per second.

        2. About portability:

          Before the ANS standard, people were complaining that there’s no effective Forth standard. I thought the ’83 standard plus a lot of things in common usage and documented in Starting Forth, Thinking Forth, Forth Dimensions, and other publications were enough of a standard; but when the ANS standard came along, it seemed to give Forth more credibility outside the inner circles. I’ve added some things from ANS to my own ’02 and ‘816 Forths, but I don’t like being confined to some parts of ANS.

          There are some parts of ANS Forth that present extra overhead in order to make it more portable across a wide range of processors. My personal opinion is that they may have taken this too far. At some point, we need to acknowledge that no language that lets you get so close to the heart of the computer will be 100% portable. We must consider the programmer(s) and platform(s) involved, and decide on a good balance between portability and optimization. I personally prefer more optimization at the expense of portability. Greater optimization means a particular processor can be used for a wider range of jobs anyway, which could in itself reduce the need for portability. If code is taken from one platform to another, modifications may be needed, but they should be rather minor.

          Jack Woehr, the president of Vesta who was on the X3J14 committee, says in his book “Forth: The New Model”, “When Forth, which some hold to be inextricably wedded to hardware, takes responsibility for cross-platform portability, a certain light-footedness and grace will be surrendered.” He admits that optimum portability and optimum efficiency don’t come at the same point. Fortunately he also says it’s not the committee’s intention to force anyone to comply with the standard. What I have is basically Forth-83 with a lot of extensions from my own experience, the books “Starting Forth” and “Thinking Forth,” Forth Dimensions magazine, ANS, and common usage.

          1. I agree. ANS effectively killed Forth by making it too big and clever. 83 was OK. ANS was like reading a philosophy and linguistics paper with syntax this and run-time semantics that. The standards club was just interested in a much different project than the serious Forth user. They were a serious pain for everyone in the business they way they sent out announcements and the industry press thought there were somehow in charge of Forth.

          2. Jack wasn’t the president of Vesta. At the time, that was Steven Sarns. Jack was one of two programmers there (I was the other). At one time, Forth was our primary development language; we did everything from pipe bending machines to multi-computer exercise machines using it. We developed ROM-based Forths for our boards, which were based on 80×88, 80C196, 68000, and 68332 processors. Most were direct-threaded interpreters based on Laxen & Perry’s version of Forth-83, but the 68332 version was a subroutine-threaded Forth compatible with ANSI Forth through dpANS-6.

            We switched to C and BASIC after we started losing sales merely for offering Forth as an option. Not my decision – our general manager back then made that decision after we had a prospective volume customer tell us, “It’s a hobby language, so your boards must be just for hobbyists.” Arguably false, but, again, not my decision.

            I still like Forth; I just don’t have much opportunity to use it these days.

      2. That’s not Kitt Peak (“those big dishes on railroad cars..”).
        That would be the Jansky VLA, I’ll wager.
        And they’re not really railroad cars.
        And they only use Hein’s Trein to transport them to and from the pedestals.

        But the Kitt Peak 36 foot telescope is intimately involved with Forth.
        Check out this gorgeous document from 1977, at:

        It’s full of dark knowledge and mythic lore, like:

        “The first thing one must do is obtain a copy of the current version of the
        KPNO Varian FORTH system on a magnetic tape. This tape may then be taken
        to any of the KPNO Varian systems, loaded into the system and executed.
        The current version of FORTH will always reside on the Kitt Peak CDC 6400 and
        the following job will copy the system onto your magnetic tape (a 600 foot
        tape is sufficient).”

    3. OpenFirmware was a great use for Forth, showing up on many PPC Macs and various ’80s and ’90s workstations. It made boot-time hardware drivers truly portable.

      Unfortunately it never got traction in the PC world, and Intel killed it off with EFI. OpenFirmware still lives on somewhat in the Linux devicetree structure.

    4. “it seems like a fairly dead language” founded By Chuck Moore the inventor of Forth and Elisabeth Rather in 1973 is still in buisiness. I guess they have enough customers to stay alive. There is also another company I know of, this one in Great Britain: Sure it is not main stream but far from dead. And these companies doesn’t sell toys. This is professionals tools suites.

      1. And it doesn’t need a supplier to stay alive. Forth has not had much commercial support because the user can get under the hood and modify the compiler on the fly and without re-compiling everything, and make it hard for a vendor to say, “You need our new version because it can do ” and you’ll just say, “Good idea!” and go implement it yourself, very quickly, without buying their product. I’ve found from the forums over the years that there are an awful lot of home-grown Forths in use, and more being developed all the time.

        1. … does this happen with C as well, or Python or ….
          In Forth the owner or programmer is the master and can decide to modify the existing ( own time invested ) or get commercial paid support/tools. If you do it for fun, there are still MPE’s LITE FREE versions to start in addition to the non-commercial Forths like Mecrisp.

    1. COBOL isn’t really that scary, it is like SQL with more boilerplate.

      There are much worse languages that fit into the “as long as it’s not” part.

      The problem with this sort of purported language agnosticism is that there is also the idea of using the right tool for the job, and so then what language to use suddenly is very relevant, but still isn’t based on personal preference. The cliche seems to muddle the two issues.

      Sometimes COBOL is a great tool. It depends on the use case.

  11. “Look at 2 + 3 * 4. There is nothing natural about getting 24 here at all”

    That’s right, its not natural at all. It should be 14.

    Also RPN is a natural way for a computer to think of math “you, and you already in my registers, go do the + operation”. But “2+3” is more natural for human brains – we’re more vectorized than full of registers. “2+3” is more like “imagine you’re at 2. You’re going to move forward. Move 3.” This fits the way we (most of us) process instructions better with states and vectors, not registers and operations. This is more than tangentially related to why humans insist on perceiving time linearly as well.

    1. I see your point about “you’re at 2, move 3”, if the mental schema is a number line. But I see 2 green blocks and 3 red blocks. “+” means put them together and count them up. When I multiply, I see identical rows all lined up in columns in my mind’s eye. For that brain, RPN is just as reasonable, if not more so.

      I’m not sure that anything about math is natural or innate. But I remember learning order of operations as a child. It was something we had to memorize, rather than something that any of us understood naturally. Are you 100% sure of the precedence order of bit-shift and assignment in C? I use parentheses sometimes where they’re not necessary, just to make the code clear. This is an artifact of the notation.

      “Do stuff in left-to-right order” doesn’t require much thought in comparison.

      1. A good point. Order of ops is natural to me (and yes I have no problems with all those ops in C or the other languages I know), but I know many people who its not natural for. I suppose both of these may be good for different people, and likely there are some that neither is good for given that our brains develop in a manner akin to “throw it against the wall and see what sticks” (more literally, try a ton of random combinations of connections and remember feedback/prune the ones that dont work).

    2. I understand the Korean language works in RPN, so Forth is more natural for them to pick up than algebraic languages. Where we would say “put on shoes,” they would say something more like “shoes install.” I started programming in algebraic at the beginning of 1982, then went to RPN a few years later and quickly came to prefer it (although I don’t speak Korean).

      1. I have been told as well that Forth comes very naturally with children, before they have started the usual maths and are conditioned to how the math books are written. As many comments here prove people understand it how they have been conditioned as well ( or have been taught whatever you prefer ). Or to go upwards a few lines : I do not understand Korean or URDU – so they must be bad as they are not English or it’s local derivative American…

  12. The first few generations of SUN workstations had FORTH in the boot ROM. It not only completely controlled the boot process, letting you interrupt it and interactively prod the hardware, but ti could also store a few scripts that allowed you to do hacks to an ailing system without having to rewrite a device driver. I once had a DSP array board that had a minor hardware flaw that caused the device driver to fail initialization. Banging on a few select registers during boot made it all work nicely.

    1. You can apparently also do odd thinks like overclock a blade 150 or ultra10 through the prom. I think everything at least from sun4c though sun4u which includes the 1.6Ghz dual Ultrasparc Ultra 45 has forth in the PROM or Openboot the latter being the newer 64bit ones which are about 10 years old now or better.

      Also, let us not forget that cards could include forth drivers in thier own rom… so you had some level of driver built into the card. For instance ethernet cards are usually smart enough to do link tests, and graphics cards include a console driver in forth. And these roms would work in 32bit and 64bit machines just alike at least the ones with SBUS anyway…

      If Sun had continued selling workstations it probably would still have forth… however they opted to go the stupid route of slow death…. selling just weak single thread massively multi-threaded servers.

      It is also worth mentioning that OpenBIOS which is the open source version of sun’s prom (a close relative at least) has support for modules written in C so you don’t absolutely have to write anything in forth to take advantage of the nice prom.

  13. No matter how useful or convenient, it is important to remember that FORTH is one of two languages I consider to be “write-only” because they make it way too easy to write code that not only confuses other coders, but can also look alien to the original author within months. (The other write-only language, for me at least, is Perl.)

    1. To paraphrase Chuck Moore : Forth is an amplifier, in hands of goods programmers it is really powerfull but in hands of bads programmers it is a disaster.

      If you can’t read your code 6 months after you written it … well, the conclusion is obvious.

      The problem is that programmers used to procedural programming (like C), don’t change their mindset when trying to learn forth. But another mindset is required to program in forth. Like another mindset is required to program in LISP. A programmer not frozen in his mindset can learn any language, provide he is ready to commit to it.
      The question is: is it worth it? You will be more lucking to find a job as a Java, C or C++ programmer than as a forth programmer.

    2. Re: “write only” Yes and no. I definitely have felt that pain, and it’s not a good sign.

      Forth, for any given application, wants to be written in layers — at least three. The first layer is written in Forth, and that’s the “write only” layer in my experience. It’s like a hardware abstraction layer for any microcontroller library. It’s got to be thouroughly tested, but that’s not hard b/c it’s usually very low-level.

      Once you’re done with that, the serious programming work happens in the middle layer(s). Since most of this is in terms of the HAL vocabulary already, it can be as readable, or more so, than other languages. “More” because Forth reads like language, rather than having all the parentheses and syntactical structures that e.g. C does — forcing you to use a syntax-coloring highlighting editor to get a grip on the code, for instance. Since this is where the “real” program logic happens, it’s great that it’s already made readable by the HAL code.

      This mindset, that you start off by coding a “domain-specific language” to handle a problem is very Forthy, although not unique to it. What I described also sounds like how people use Arduino or any of the other microcontroller libraries — they take the HAL part as a given and make up their program out of these primitives (analogRead(), etc).

      The top level is then for “users”. The vocabulary is small, succinct, and does (only) what you’d want a user to do with the system. If the programmer is the user, this is flexible, of course. But this is like the “public” interface for toplevel objects in a good OO library, or the main() loop in C.

      Except that it’s interactive in Forth: you’ve just built a system for interacting simply with your device rather than a monolithic program. That your code directly ends up being the user interface at the outermost level, is unique (?) and powerful. For instance, you don’t have to write up test runner programs to test your library functions, you just use them. (If you’re serious, though, you can write the tests down…)

      Anyway, I’ll demo this with code instead of words in the next article. Talk is cheap, code convinces. :)

    3. I assure you it is possible to write highly readable code in Forth.
      The important thing is to remember that subroutine calls cost little or nothing, so hide all of the “?dup over !” type stuff in sensibly-named word definitions.
      Forth also lends itself to creating domain specific languages.

      As for Perl, I tell it to “use English;” on the first line of every program. Doesn’t help for reading other people’s code.

    4. Write only? You don’t have enough grey in your beard.
      Try APL (i’ve long since lost my IBM Selectric type ball for it :-() if you are a vintage IBM fan or TECO if you miss the old DEC PDPs. Both predated FORTH and have thier niche and rabid fans,
      Verbosity is not necesarily a virtue, but terse but powerful languages does raise the bar too high to attract the cool kids and lemmings who prizes popularity and trendiness above all else.

      1. Or the latest version of APL… (which at least uses the ASCII character set!) which is called J

        It’s… interesting. Like exactly the opposite of forth. Far more terse, but more built around describing how data is to be processed… and does nothing until you’ve finished giving it everything. Then it more or less runs from right to left.

        Most interesting is the way it combines words to describe ‘higher dimensional’ parallel processing. So much so that if you have a word in J to operate on one data cell… it can immediately be used on any dimension of array, and applied in a variety of ways as well, such as ‘between’ elements, as well as in parallel, without rewriting the word.


  14. Forth. Hmmm well — I have been hanging around Forth for years (since I work in the Astronomical community where it was birthed, or at least nurtured). On about an 8 year cycle I get some itch to fiddle with it again and go have a chat with “Alan” who loves Forth and remembers it from the good old days. After a chat with him I am usually cured for another 8 years. At this point I think I am cured entirely. Someone has already mentioned that the bootroms in early sparc based suns (sun4 boards) have forth in the boot roms. A bad idea whose time had come apparently…. and went.

    I remind myself of the whole stack based RPN business and that provides an almost immediate cure now.

    The photos of those STM32 controllers is intriguing. I may give one of those to Alan and point him to this article (since I have 2 dozen of those in a box right over here …..)

  15. Tangent – I recently went out to everyone’s favorite online vendor to get a new HP RPN calculator, only to find that they only sell 1 model. This didn’t surprise me that much but what shocked me is the old 32S and 15C are now collector’s items. A “new” 32Sii is $900.

    1. I was heartbroken when my HP11C, bought in 1981, died in the mid 90’s. And I gratefully snapped up one of the HP15C LImited Editions when they became available; mine is S/N 02408. It always irked me that the HP12C business version has been available continuously but the engineering calculators were discontinued. The landscape mode HP RPN calculators are just a joy to operate compared to others. (The Limited Edition actually sports an ARM processor running an emulation of the original Saturn CPU running the original ROM, and except for the fact that it is about 100 times faster than the original it’s like the original in every way.)

    1. It is funny to read it because, forth is an extensible language. One can extend it to any level of abstraction. With LISP and smalltalk it is the most easily extensible language available. You don’t like to bother about data stack management. Extend the language to hide it. You need automatic memory management? Again extend the language. You want OOP, same story. Like LISP it is not a low level or high level language it is at the level of abstraction you want it. And doing all this is interactive and seamless.

      The problem with all those forth tutorials is that they only show the low level basic system and this deserve the power and elegance of forth. What’s that RPN thing? ugly! What’s that 2 stacks to manage? disgusting! This is only the core of the system, from it you can build at any level of abstraction. 3 languages should be remembered in history of computer science for their great elegance, which come from simplicity: LISP, forth and smalltalk. And none of them is main stream.

      1. Does Forth have something like a stdlib ? Raw C would be pretty useless, and a lot like base-level Forth sounds, without the libraries that everyone thinks of as part of the language. Otherwise it seems like you’d suffer a lot of wheel-reinventing.

        Or does each Forth programmer take his own library around with him? That’d surely be difficult for sharing code, which is another good thing C has, everything you’d ever want to do on a computer, somebody’s written already in C. And they used standard libraries, so you can understand what the code does.

        Cos it does seem a little bit like Forth is something where you create 90% of the language yourself, Forth itself looks a bit like a very primitive assembler, except without even the functions that are now single opcodes in CPUs.

        That’s all going by this article, so I’m open to be corrected.

        1. Greenaum, I have not used high-end Forths (like the 32-bit or more ones that have been used for airport and hospital administration, DSP, etc); but I know there’s a lot there. See for example. Regarding the single opcodes in CPUs, the fastest Forths are on stack processors where the machine language basically _is_ Forth, and it does more than one Forth primitive per clock cycle, IOW, more MIPS than MHz.

        2. How much will it cost you to show that your STLIB is free of security or safety critical bugs? How much memory it need? Would you still use it in something that you can’t simply update in the field? Sometimes the cost of abstractions is higher than you’d be able to pay.

          Your second statement, Forth is nothing but a primitive assembler, is a frequent argument. Yes, Forth is an assembler, but it’s one that’s coded in Forth. It’s a machine making machine inside the machine. Comparing C to Forth isn’t meaningful, the same applies to comparing C to LISP.

          A lost thought: C programmers railing at Forth are much like the single language speaker railing at the polyglot who has a good time chatting in a different tongue.

  16. I jumped onto the mecrisp for ARM (& jeelabs) bandwagon a few months ago and so far I’m enjoying it. It’s great to make microcontrollers do simple things. It’s awesome to be able to live-debug and test stuff interactively. But there is no denying that there’s a learning curve. Managing the stack is one, and then learning not to over-use the stack and write tiny words is another. I’ve come to hate C++ (personal opinion) and the fact that anything arduino rapidly plunges into excessive C++ complexity. I’ve spent quite some effort on Espruino on the esp8266 (javascript interpreter) and while it’s an awesome project and the programming is fun, the end result is too sluggish for my taste. So while forth is undeniably lower level than javascript, it has the same interactive no-toolchain feel to it that makes things fun and also easier to maintain, and it has down-to-the-metal performance.

  17. I think Forth should be combined with Node.js to create … let’s call it Forde.js. A language is hard to write AND won’t execute statements in order. Only real programmers need apply.

      1. My recommendation: google for Forth Java!
        There are several Forth versions written in Java.
        One example: JForth: Implementing Forth in Java, written by Craig A. Lindley, May 21, 2008, published at

        Another recommendation: Google for Forth Node.js!
        There you will find “A FORTH running on HTA, HTML, Node.js, NW.js, Chrome Extension, Chrome App, and more” on

        What else do you need?
        Googling first before using alternative facts is always a good idea!

  18. IMHO the best thing about Forth is that due to the way the compiler is so deeply integrated with the language and interactive environment, it’s a first-class language, on a par with Lisp and capable of doing things that just aren’t possible in ‘C’, ‘C++’, or Java. Learning it teaches you new ways to think, giving you powerful mental tools even when applied to other languages.

    I first came across Forth in 1981 (Personal Computer World article “Go Forth And Multiply”) and found it mind-blowing. I did a bit of Forth stuff over the years, but it wasn’t until 2011 that I decided to take it seriously enough to design FIGnition, a retro-8-bit DIY computer around it. Unlike an arduino Forth, or amForth, FIGnition is a purely self-contained system, with a keypad for programming; video out and audio in/out; and it’s been featured a few times on Hackaday.

    I’ve sold over a thousand and although I’m out of stock, RS-components in the UK still has 35 left. Check it out, it’s lots of fun being able to use and program a computer you’ve actually built!

  19. I’ve always loved the idea of Forth. I’ve loved RPN calculators since I got my HP11C in 1981 and I’ve done a few FORTH-y things over the years, such as emulating a PLC with the original ladder diagram translated to a Forth-like interlanguage. But I’ve never managed to find a situation where I could actually use Forth to solve a big problem. I think Forth is a perfect tool to solve some of the problems that I’ve worked on, but for one reason or another it wasn’t an option. I even got a Wikireader because I knew it could be programmed in Forth, and while I got it to say HELLO WORLD I never really got a chance to do much else with it. (Documentation would have been helpful.) I have started to design at least a dozen implementations of Forth or Forth-like languages on various industrial devices, but other than the aforementioned PLC emulated on a PC, none of them have ever come to fruition. I’d really like to close the loop some day and do a real system with real Forth, if only because everything I’ve ever read about Chuck Moore makes me think we must have been separated at birth.

  20. I dunno. I like Forth, conceptually. I’ve implemented RPN “expression evaluators” a couple of times, based on what I learned from looking at Forth, way back when. But I sort-of wish it had … Grown out of its early-70s fascination with overly concise keywords and funky punctuation (within keywords!), and picked up some of the “modern practices” that most of todays languages copied from each other. (comemnts, formatting, structured data, filesystems, cheap big storage and fast communications. Every time I see something like “: s abs 3C mod dup 1D > if 3C swap – then dup E > if” I get these painful flashbacks to APL and TECO.) (Yes, I’m aware that these can all be implemented and/or used in Forth as well (and in assembler. But that’s not what seems to happen.)
    Of course, if you replaced all those “words” whose names started with numbers, or contained weird punctuation or directly contradicted most other languages, I guess you wouldn’t have Forth anymore. Maybe you’d have Postscript :-)

    1. It may depend on how an individual’s mind works. I started with infix (algebraic) 35 years ago, and a few years later went to RPN and soon came to prefer it. A few years after that, I got into Forth and like it so much I don’t ever want to see another infix language again.

  21. (pedant hat on) “get.broccoli chop.broccoli get.beef slice.beef get.oyster-sauce stir.fry” doesn’t seem that RPNy to me…

    how bout ‘”broccoli” get chop “beef” slice “oyster-sauce” get stir-fry’?

    I’ve never really written FORTH though, myself…

    1. If Forth uses RPN, then C, java etc. use FPN (Froward Polish Notation).
      C code might call a function with: compare(Num1, Num2);
      Forth would call the same function with (Num1, Num2)compare

      1. Technically it’s called prefix notation. But yes, imperative functional languages like ‘C’ tend towards prefix notation due to limitations in syntax. Languages like smalltalk or C++ can support a degree of infix notation, for example in C++ you can defend methods whose names are operators such as + or – . Smalltalk also did this except that it was more naturally built into the language.

        So, for example if you have an object ‘on the stack’:

        e.g. you define: Car myCar;

        you initialise it: myCar start

        In Forth and Smalltalk you can make oo type languages quite ‘natural’:

        Forth: myCar 20 kph/s accelerate 10 seconds later kLeft turn 15 seconds later kRight turn brake

        myCar accelerate: 20 later: 10 turn: kLeft later:15 turn: kRight brake

        This is possible because every method returns its object ready to be used by the next method.

    2. re: “broccoli get chop beef slice” You’re right, your code looks much better. In fact, the error of my ways would be immediately obvious if I had tried to actually implement these words: : get.broccoli broccoli get ; : chop.broccoli chop ; just looks dumb.

      Better still is to get rid of the get entirely: broccoli should go get the broccoli. Then you’ve just got broccoli chop beef slice oyster.sauce stir.fry. That’s more like it.

      Thanks. It’s ironically easier to make good examples with real code.

    3. You are correct. And if you design well RPN code can look more like English. Here are some example extensions I have written.


      Or an interface to the TMS9919 sound chip:
      : BEEP ( — ) GEN1 1398 Hz -4 dB 170 mS MUTE ;
      : HONK ( — ) GEN1 218 Hz 0 dB 170 mS MUTE ;

      I write Forth so I can read it 10 years later.

  22. I’ve always been a Forth proponent, but haven’t gotten to do as many projects as I’d have liked in it.

    15 or 16 years ago I built up a Z80 SBC board to test the idea of using a Compact Flash card as storage for a CP/M machine, using only a Z8420 (PIO) to drive it ( I used Forth for the boot monitor as it was easy to modify the code interactively while debugging instead of burn and churn with an EPROM programmer.

    I’ve used Forth on a couple of PIC18 projects, a port of CH Tings Forth on a 8031 for a handheld device to enter fuel purchases for tracking MPG, and a few other minor things. I also wrote a Forth interpreter in C for a piece of test equipment, to allow testers to string words together to run a series of tests (it also supported strings as a data type to make life easier for anyone who had to write their own test words).

    Forth used to be one of the first languages brought up on a new architecture. With only 15 or 16 words needing to be written in assembly, it was extremely easy to port to any machine that already had an assembler, and only slightly more difficult if it didn’t.

    Most people who haven’t used Forth will parrot the statement that Forth is a write-only language. And without proper documentation, that’s a fairly accurate statement, especially when you start making use of immediate words in definitions and deferred words (one of the more powerful parts of Forth). And if you’re old-school Forth and still use screens instead of files for source, it’s even more true. Of course, without much effort you can write write-only code in most any language.

  23. I think you’re overstating the case when you say that the stack-manipulation is a “disaster”. It takes some time to become completely comfortable with it, but it’s at the heart of what makes Forth so powerful.

    For a modern, application-centric Forth derivative, take a look at ‘8th’. I’m the author, so don’t hold back…

  24. I’m presently working on a forth project. A single board computer based on PIC24EP512GP202. I’m still working on the core development. The outer interpreter and the compiler are not done yet. When completed it will be have an interactive shell and applications will be loaded an run from SD card. The display is text only 25 lines, 64 characters. The project is specifically design as a Forth explorer hence is name.

  25. Forth is probably easier to work with if you build an expression/parse tree out of your algorithm. That should encapsulate the order you need operations to happen and once it’s there should be trivial to unroll into Forth or even Lisp.

    1. If you’re going to put that much work into the design phase, implementation in any language should be trivial to unroll. Might as well just write your tree to be an input to a code generator at that point, though.

  26. Anyone who really wants to understand Forth and its implementation would find the book Threaded Interpretive Languages: Their Design and Implementation by Loeliger invaluable. There is also the August 1980 issue of Byte Magazine that is dedicated to Forth which can easily be found for perusal or download online at several places.

  27. Mecrisp-Forth is an amazing piece of work. The more you dig into its implementation, the more impressed you’ll be at what you can do with such a tiny footprint.

    I used Mecrisp-Forth, along with some of the JeeLabs libraries as a starting point for my Fluke 8050A graphical LCD replacement project. I had seen a few of these done before (on a PIC CPU and perhaps others) and thought this would be a fun project to reproduce.. I run it on a Maple MIni “clone”; an STM32F103CBT6 device with 20K of RAM and 128K of Flash. This was plenty of space, even accounting for all of the LCD fonts encoded in the flash image… And FAST!

    I’m doing bit-banging in Forth, looking for strobe signals from the existing microprocessor in the Fluke, driving the 7 segment LCD display. The strobe signals are 130 microseconds wide and 384 microseconds apart and I just stupidly poll for them in the Forth code rather than set up an interrupt handler, etc. It’s a wonderful platform for interactive exploration of mysterious hardware; you can just interactively poke at stuff and skip the edit/compile/link/download/reboot cycle. if you’re interested in seeing some info, and for some Forth code. This is my first “real” effort writing Forth code for more than just something trivial, so much was learned along the way.. this probably ought not to be the basis of a Forth coding style guide.

  28. Going cheaper… the STM8 on a board for 0.70$, with eForth:
    I prefer C based forth, because adding external C libs, like arduino or HALs are much easier.
    For the esp8266, with Arduino libs, the ESP8266Forth:
    or CForth: for ARM’s like Teeny and ESP32.
    Interesting projects: because it’s forth in 5 files and not too big.
    FICL (Forth Inspired Command Line) origin of the openboot & the fth project do work on the STM32F4Discos, restricted on the ESP32, and any arm/i386 Linux/Mac/Win, I specially liked it on the mac with a obj-C runtime binding.

    1. I’m just getting started with stm8ef, and given the limits of the platform it’s surprisingly powerful. @Thomas has done a great job so far, and even as a Forth noob such as myself I found it easy to bring it up on a new board and start poking at peripherals.

      1. The nice thing about the STM8S is that it’s minor item on the BOM of very cheap devices like voltmeters, DC/DC converters or thermostats. A Forth console on such a lifts it to great level of “hackability”: it adds free automation (as in free beer)!
        @ajlitt started exploring this world of real µC hacking, and helped make the code better by testing and by providing new use cases. Thanks!

  29. Forth isn’t very good with different types. The philosophy of “2 3 +” works fine as long as you’re dealing with a standard integer format and stack width, because the ‘+’ can’t see the type of the values on the stack.

    Mixing integers (of different size and signedness) and floats (of different precision) either requires ugly extra operators, or very wasteful stack usage.

    1. I’m very glad it’s not typed. I see C’s way as a nightmare. The vast majority of the numbers you deal with in embedded control are single-precision integers anyway, and for many of these, signed and unsigned get the same operators. + for example is the same whether the numbers are signed or not.

      It works well to put floating-point numbers on their own stack, but it doesn’t need to be more than 4 or 6 levels deep, and the reason HP did a stack on its calculators was because it saved registers back when they were very expensive in silicon real estate.

      Floating-point math puts a big overhead on a computer that doesn’t have a floating-point coprocessor; but we really do need floating-point for all but the simplest operations—or do we?? Can we really do things like trig, log, and square-root functions without floating point?

      The answer of course is yes, we can do it, and very well.

      In 1987 I wrote a small set of 7-digit decimal floating-point functions in 6502 assembly for a product at work. What a lot of clock cycles it took! A couple of years later I was introduced to fixed-point and scaled-integer math, how you typically use 16-bit cells (sometimes with 32-bit intermediate results, as in */) on 8-bit computers, and scale the needed range of numbers to what the cells can handle. At first I was skeptical; but eventually I came to prefer it (in systems with no floating-point coprocessor). I wrote the software for some automated test equipment without floating-point. There will always be a place for floating-point, especially with calculators where the applicable ranges cannot be anticipated; but I have mostly quit using floating-point for data acquisition and control for everything up to and including the fast Fourier transform (FFT) for spectral analysis. Digital signal processing is frequently done without floating-point.

      1. I use 8, 16, 32, and 64 bit integers in embedded control apps, both signed and unsigned, as well as floating point. Floating point coprocessors are becoming available in < $10 processors, so there's no big overhead, and you can use them whenever it suits the application. For fun, try implementing all the ITS-90 polynomials for different thermocouple types using scaled integer, while making sure you get maximum precision and no overflows.

        In case you're wondering, 64 bit is handy when you want to keep microsecond timestamps that don't overflow after an hour. 64 bit is also useful for keeping intermediate results of 32 * 32 multiplies.

        1. $10 for a microprocessor or microcontroller is far too expensive for many (most?) embedded-control products.

          Without having looked into it, I suspect processors with floating-point units are nearly always at least 32-bit, so their standard stack cell will be 32 bits wide, even for 8- and 16-bit quantities, and */ automatically has a 64-bit intermediate result, ie, a double. A 32-bit floating-point number will take just one cell on the data stack. A 64-bit processor’s standard data-stack cell size will be 64 bits, and a double will be 128 which can represent approximately ±1.7E38. I’ve only used 16-bit Forths, on machines without a hardware floating-point unit. I have math libraries for triple (48-bit) and quad (64-bit) precision and floating-point, but I have never needed them.

          The thermocouple thing is interesting, but thermocouples are so slow there’s no speed requirement for the computation. Further, few things need as much precision as most people think. Even among audio professionals, there are a lot of firmly entrenched myths about the required number of bits, what parts of the recording/reproduction chain are causing the distortion, etc.. See . (YouTube uses lossy compression for the sound; but the video tells you where you can download the raw, uncompressed audio data discussed.) The best of the high-end music cassettes were impressive just before CDs took over, but you can do even much higher quality music reproduction with digital using only 10-12 bits of precision.

          I am constantly challenged by the essay, “Low-Fat Computing (A Politically Incorrect Essay by Jeff Fox),” at . He and Chuck Moore (inventor of Forth), taking an entirely different programming philosophy, plus Forth hardware and software, have improved the compactness and speed of code by factors of anywhere from 100 to 1000.

          FWIW, I never get programming errors in Forth from type mismatches.

          1. Jeff Fox is a good guy. Back about 15 years ago there was a Forth processor that either he or Moore designed that was around 100 MIPS or so. Fetched 5 4-bit instructions or maybe 4 5-bit instructions at a time. I really wanted to do something with it back then, but didn’t have the PCB layout tools. I just looked at the Chips page on his site, couldn’t figure out which one it might have been.

            I do have several of the 68HC11’s with New Micros Forth in ROM, and a dozen of the Rockwell R65F11’s. One of the chip decapper groups really wants one of them to decap and photograph the die. Seeing as I’ll likely never use all 12, I should put one in the mail.

          2. I’m looking at doing trig on a PIC to revive an old project of mine. I was originally going to just use a lookup table in the PIC16C56 days but now they are so fast I might just be able to do the math on the fly.

          3. I ported Rockwell’s RSC-Forth to Mitsubishi’s M38049 8 Bit 6502 compatible micro controller and added Mitsubishi’s Floating Point Package with 12 digits BCD number addition, subtraction, multiplication, and division.

          4. Your answer perfectly highlights the problem. Different Forth implementations will have different stack sizes. In my 25 years of embedded work, I’ve collected tens of thousands of lines of C code libraries, using different widths and precisions for the variables. All of this code can be easily ported between 8 bit AVR targets, 32 bit ARM and 64 bit x86. In Forth, your code developed on a 32 bit ARM may not run on an 8 bit AVR without rewriting it using different operators.

            You may compliment yourself that the 8 bit AVR rewrite is low-fat and super compact. My customers compliment me on the fact that I only bill them for 15 minutes to grab some existing code, and add it to their project.

            “but thermocouples are so slow there’s no speed requirement for the computation” — sure, but that’s only more reason to implement the code in floating point even on small targets without FPU.

            “Further, few things need as much precision as most people think” — sure, optimizing to use the perfect number of bits and the smallest target is often a waste of time, when you can get a 32 bit CPU for the same price.

          5. I’ve read quite a few stories where for example it was estimated that a particular project would take a team of C programmers two years to do, but one man came in and did it my himself in Forth in six months, reducing the hardware requirements in the process. Such history of cases indicates that Forth tends to be much faster to develop. Elsewhere on this page, I mentioned the ANS Forth standard which was formed to improve portability, but that it has not always been well received, because portability is not necessarily the most important thing in a language where the application can be completely re-written much faster than a C program can be debugged.

    1. That’s a bit like asking if Arduino code would run on a Linux box. The answer is probably kinda “yes”, but without the physically attached hardware, it’s also “no”.

      Or do you mean, will you be able to follow along if you run windows/linux/mac? The answer is yes.

    1. Any of those _should_ work if they’re selling what they claim — i.e. an FTDI chip as serial converter. The other chips out there seem to work just fine too, and may be even cheaper (or more likely to not be counterfeit at a given price point).

      In principle, getting USB/serial done should be a no-brainer, and thus should be reasonably cheap.

      Eugene brings up a good point as well — any Arduino Uno or similar has a USB/serial converter inside already. The old ones have an FTDI chip, and the new ones have an AVR that’s programmed to do the conversion.

      If you can pop out the big (socketed) AVR, you’ll be able to use the TX and RX pinouts on the board, because that’s how your computer speaks to the Arduino anyway.

      1. Yes, they should work, the issue is on Windows or Apple you have to roll the driver back to the older one that doesn’t disable counterfit chips. Its easier to use the Arduino one because the Arduino foundation hasn’t put any counterfit disable code in their drivers. Or just Use Linux.

  30. I just noticed this would technically be backwards “Forth is what you’d get if Python slept with Assembly”

    Forth came before Python so you would have Assembly sleeping with your Daughter Python to produce your mother Forth. :)

    You ought to do a tutorial on the Arduino and/or PIC as well.

    1. I am writing Forth programs since 1984, making a living with it, being self employed.

      You may not hear a lot about people writing Forth programs, because for decades Forth was one of the best-kept secrets in the computing world. This is no exaggeration: large corporations have purchased professional Forth development systems from vendors such as Laboratory Microsystems, Inc., Forth, Inc. or MicroProcessor Engineer, Ltd. and sworn them to secrecy.
      Source: Julian V. Noble,

      1. I hear those stories, but I claim BS, unless someone can show some real examples. Surely, there must be Forth enthusiasts with large projects that they put on github or something, just like there are tons of good C projects out there.

        1. There’s a list of NASA-supplied Forth usage examples in featured space applications at . There’s a partial list of Forth, Inc.’s customers who use Forth at, including such notables at Lockheed-Martin, Apple, Boeing, Sun Microsystems, Sandia National Laboratories, Los Alamos National Laboratory, TI, General Dynamics, and FedEx. Forth, Inc. has some featured Forth applications at . These are all applications of Forth, Inc.’s products; but I think Forth, Inc. only has the tip of the high end of the Forth market. There have been other major suppliers of Forth over the decades, but a lot of Forth kernels seem to be developed separately from those, partly because it’s just not that difficult to roll your own. I use Forth on the workbench in the development of most of our aircraft-communications products. I just started doing some consulting on a spacecraft project on the side, and although there’s no Forth at this company yet, it wouldn’t surprise me a bit if I get to bring Forth in there, too.

          1. But where are the open source projects ? There are millions of projects in C, with thousands of really big and well made ones. Where’s the Forth equivalent ? Or could it be that Forth isn’t suitable for similar projects, and only good for trivial control tasks ?

          2. Forth projects are mainly commercial projects. As I wrote before, I am using Forth since 1984, and I used it for my customers projects. For myself I wrote simple programs like editors and IDEs, specialized for my own usage. Some years ago I started to do my taxes using a few pages of Forth, written in Win32Forth, which has a lot of demos and applications. The Forth world is different, but easy to learn. Forth is increasing my abilities. Many projects I could only do because of Forth.
            To make it easy for others, we started a “Forth for Education” which you will find at

  31. I am always amused when I read about RPN Reverse Polish Notation. This is a mathematical definition – which is fine. Actually, this is how you work at your desk, how cars are manufactured and many other procedures. It is serial processing on a conveyer belt: As done at your desk. work coming in from the left, serially. And results out at the right. On incoming work you have to decide what to do with it. Act on it immediately, fine; or put it on the Data Stack for later use ( actually I have about 4 stacks on my desk for different activities). A couple of pidgeon holes for the variables I work on. And then the boss comes in, You stop the current work, put the current address onto the Return Stack and do what you have been told to do; when done, get your return address from the Return Stack and continue where you had been interrupted. Rather than thinking about what to do when, this procedure forces you to think about what to do when before – if cars are built this way there must be a reason. You want to try it out? go to download the .exe and start going through the code, try it out. The little application just needs 4 pages to print out. Or if you want to read about it, there is a selection of ebooks at including Starting Forth – the classic and Chuck’s 2 eBooks – how Forth started and the insides. Or for a bit of Retro: the FIG-Forth Manual, and you can run it yourself using the good old 1802 IP in a Lattice FPGA Board..

    1. Pushing values on the stack first and have the operators pop them off is a very simple method, as long as you don’t care about context or types. A language like C will look at the entire expression A + B before deciding how to represent A and B, and what ‘+’ operator to use for evaluation, which allows for much better optimization, safety and flexibility. In Forth, the expression ‘127’ by itself gives no clue whether you want a signed byte, or an unsigned 64 bit, or maybe even quadruple precision 128 bit float.

      1. A language like Forth is different to a language like C as you know very well. You test new Forth words as you code them, and they are a line or 2 long max, you know what you are doing. And after testing, this new part of the program is not touched anymore as there is no need ( if possible ). It is a different approach to problem solving. As well Interactive Debugging. There is no point if the 2 languages are too different to compare really. One group will not look over the fence and stay where they are. Another group compare and decide – or the boss decides anyway and you adapt or go. Many people here do not have an idea what Forth is as is visible from the comments. For this reason I posted the links. And these links are mostly for people who start from scratch. Different approaches for different programmers for different projects for different requirements.
        To allow for the Forth advantages to be used by C/C++ programmers, MPE Forth has introduced Sockpuppet to link the 2 languages, actually based on a large OEM. And as a general summary to many points here: If C is better anyway and no interest to learn something new – what is the point. Both have about the same age and are used by different programmers – actually often these use BOTH – dependent on the problem to be solved in the fastest way. For this reason the word came up, that Forth programmers solve the problem quicker – one simple explanation amongst others: they use two different tools rather than only one.
        And as we are on Hackaday – as you can bend any rule ( nearly ) in Forth, it should be suited very well to those who dare …

        1. Forth programmers probably solve some problems quicker because those were problems that happened to suit Forth. Most problems don’t suit Forth, and we simply don’t hear about them.

          1. Sure, it’s a good idea to use a tool that suits the problem best, but if it only suits a particular small niche of problems, don’t boast how it’s a great tool for everything.

            On the other hand, there’s also an advantage of using the same tool for all your problems, even if not necessarily the best for each individual problem.

          2. Forth is a niche language – I assume we can agree on this – and as I have been told, people get well paid. What is the best language anyway? How do you define this. Sure you can use the same language everywhere – but reality shows there is more than one – WHY

          3. Everybody has his own reality. That’s why different people are solving different problems.
            I am using Forth since 1984, and only once I had to use C, because I didn’t buy a commercial Forth five years ago, a free Forth didn’t fit into the MSP430F2012 which I needed for my battery powered project. Now there is mecrisp-across which is a free cross-compiler for these memory restricted buggers.
            I even do my taxes with a few pages of Forth code, saving a lot of work, and I wrote a Forth program to generate websites, using a FTP upload written in Win32Forth.
            What problem do you have which you think cannot be solved using Forth?

  32. @Elliot Williams: I looking forward for your hands-on tutorial. It’ll be a great service for the community. But would it be possible to add some kind of sensor, for example, to show how one could connect and read from the sensor in Forth? It’d be outstanding!

    1. There are hundreds of Forth Tutorials on the Internet, just google for it.
      If you are looking for a sensor example, what about 1wire temperature sensor?
      Googling for 1wire Forth you will find a lot of solutions for different micros, and there is an application note at for which I wrote a part of the Forth programs used.
      Forth is always a good choice to connect sensors!

    2. @Luis Mendes: Forth for connected sensors is fun, really. Check out Elliot’s other post on a MQTT connected sensor made with Forth here on Hackaday. One of my goals is building an sensor/actuator network, like LIN or CANopen, with console side channel, similar to what SENT (SAE J2716) provides.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s