A Simple Forth Development Board

forth

Forth is a very interesting programming language. It’s very flexible and is extremely efficient on low powered hardware, but unfortunately not very popular simply due to the fact that it’s not very popular. There were a few Forth-based microcomputers built in the 1980s, but these were largely unsuccessful.

[Leon] is a Forth aficionado and came up with his own Forth development board in the hopes of Forth making a comeback. It’s a very small and cheap board – only about $12 in parts – but it’s still extremely powerful and a fun platform for investigating Forth.

Compared to other programming languages found in 80s microcomputers, Forth is just weird. It’s a stack-based language, so instead of adding two numbers like 3 + 4, Forth uses postfix notation (or Reverse Polish Notation) so the same statement is expressed as 3 4 +. It’s a much more efficient way for computers to handle data, and some claim it’s more efficient for humans as well.

[Leon] created his own board able to be programmed in Forth, shown above, that uses an ATMega328 microcontroller. He’s using AmForth to put Forth on his system, but also extended the base AmForth install with his own floating point version. making this version of Forth at least as powerful as any 80s microcomputer or ATMega development board is today.

[Leon] put together a great demo of the capabilities of Forth and his dev board. You can check that out below.

74 thoughts on “A Simple Forth Development Board

  1. > not very popular simply due to the fact that it’s not very popular.

    Probably also not popular because stack manipulation doesn’t match how most of us tend to intuitively think about computation.

      1. I disagree. Humans intuitively work with information by associating it with other information (e.g by naming it, like we name variables in mathematics or in C or Python etc). Nobody naturally thinks by pushing data onto a stack and doing DUP and ROT and SWAP in their head.

        1. To be fair to John here, I think you have to admit that there’s really not a lot of naturality to things like parenthesis and the order of operations. You had to memorize “PEMDAS” for parenthesis, exponents, multiplication, division, addition, and subtraction.

          RPN is actually a nice way to resolve that issue. The order of operations doesn’t need to exist, the way you write the equation sucessfully shows what order you *meant* to apply the operations in:
          3 4 + 3 *

          Now instead of thinking about this as a stack, just imagine thinking about it as if you were reading it on a page. You stop when you see the plus and take everything you’ve read so far and add it together, and then you replace what you saw:

          3 4 + 3 *
          Take 3 and 4, add them together: 7
          7 3 *
          Then you repeat, replace the 7 and 3 with the product: 21
          21
          And you have your answer.

          If you worked like this in school, “showing your work” would have you successively performing operations and replacing them with the result like this! This is also very natural compared to how we read in English: left-to-right and you understand the whole operation*.

          If I tried to write this with in-fix notation, we would see (3 + 4) * 3
          But understanding why that’s different than 3 + 4 * 3
          Requires you to know more than just what the operations do and how to read left-to-right.
          ————————————–
          * The whole left-to-right thing only works if you write out the equation in what’s called the “chain calculation” method. You can write hella confusing RPN stuff once you know it’s a stack
          3 3 4 + *
          Is the same equation as above. The only real difference in reading here is that “replacement” happens to the two operations immediately preceeding the operation. You don’t have to refer to it as a stack at any point.

          1. My favorite definition of the word “Intuition” is “The act of complex pattern matching performed at a subconscious level”.

            Given that definition, I believe ‘intuitively’ was the correct word. I’d argue that people of MOST cultures can quickly evaluate simple mathematical expressions using subconscious pattern matching. In fact, probably the ONLY people that would find RPN easier would be those with NO previous exposure to math. Even then I’m not sure they would find it easier…

            BTW, my first exposure to RPN was with one of the first “cheap” LED handheld calculators. It required the entry of all calculations in RPN. My family got it when I was about 8, so I was at about 3-4 grade math level. I was the ONLY person in the family that could use it. It was ANYTHING but intuitive. Frustrating as crap, but NOT intuitive…

            Of course, one could argue that I’d already been culturally “polluted” by having taken 4th grade math. The point is that it’ll be hard to find the correct “culture” to embrace stack based coding :)

        2. It is my understanding that the Korean language is postfix, so native Korean speakers tend to find Forth a lot more natural than native English speakers do. I started with algebraic, then went to RPN in the 1980’s when I got into the 41cx calculator for instrumentation control and automation and data acquisition since it can talk to lots of IEEE-488 lab instruments at once. For a while, I could go either way, but soon got to where I never wanted to see another algebraic language again. So yes, I’ve become a strong Forth proponent.

    1. Any language in which you can redefine “1” to be something different and the language doesn’t bat an eye is a language which is dangerous. Check it out! (using gforth)

      : 1 2 ; ok
      1 1 + ok
      . 4 ok

      That’s right! 1 + 1 = 4

      The issue here is typing. There’s no differentiation between the number 1 and the named object one. There’s no separation of name spaces. People say things like “C is powerful but dangerous,” but I had a professor who once told me: “Programming in C is like walking through a workshop filled with bandsaws with no guards on the blades. Programming in forth is like turning off the lights on the guy walking around in that workshop” (and this was a professor who *loved* forth)

      There are a lot of reasons why forth fell out of favor. I could ramble on and on about them. I think a lot of them simply have to do with the fact that we can provide a more functional experience with better syntactical sugar, better type checking, and that computers have enough horse power in general to just run more straightforward code. We can afford the cost of multi-pass compilation and strict type-checking. In uncompiled languages (ruby, python, etc), we can provide better syntaxes which make for more readable code.

      Last but not least: http://globalnerdy.com/wordpress/wp-content/uploads/2007/09/forth_on_the_atari.jpg

      1. I agree and I used to program on FORTH. The other part you did not mention is because you are adding commands to the library FORTH becomes a very personal language. If you develop an application in FORTH, then handed that app of to me to work on, the end result would be a disaster even with excellent documentation!!!!

        But FORTH is a neat language and probably one of the first if not the first true object oriented language. Now you’ve done it, I’m going to have to drag out my old FORTH books. Wonder if anyone wrote a FORTH compiler for PIC?

      2. “Forth zealots take [it’s power to weight ratio] as one of many signs that Forth is the One-True-Langauge. I disagree; modern desktops and laptops are so powerful that a great power to weight ratio is unnecessary. Generally I’d rather use a language with dynamic typing, automatic memory management, many libraries available, etc. [B]  However, microcontrollers don’t have cycles to burn, making Forth an appealing choice.”
        -TFA

    2. Actually your mind does have a stack, it’s just that it behaves more like a conveyor belt. (did you see that cool “conveyor machine” CPU design?) in that it’s always moving, and only ~ 7 deep. The 8th thing gets dropped.

      A stack machine is normally implemented in memory so that it tries to never drop anything, much like we always want our machines to be as correct and as deterministic as possible.

      Our minds aren’t though. Follow a train of thought through 7 steps or so, and you’ll forget what you were thinking about originally.

      If you just read a couple of numbers, you’ll probably easily remember the last couple, without even trying. But more than 5 or so and you will need to put them together into a larger, more complex “single” object, and remember that instead. Our minds may be good for only 7 “stack locations / conveyor addresses”, but there isn’t really a limit on how many bits of info can be referenced by each one. Much like passing by reference really.

      1. I watched all the videos related to Mill CPU architecture and I remain skeptical of the whole belt idea, but no one responded to my comments :'(
        http://hackaday.com/2013/08/02/the-mill-cpu-architecture/#comment-1035542

        Ignoring that, saying that you have a stack but it behaves like a conveyor belt is the same as saying that you have a queue, and a queue is not a stack. In fact, it takes two stacks to implement a queue!
        http://stackoverflow.com/questions/69192/how-to-implement-a-queue-using-two-stacks

        And skipping past that point, I think what Angus was trying to say was that people tend to think in steps, i.e. do step 1 and save the result in A, then do step 2 and save the result in B, then do step 3 and use A and B. Because people do reasonably well with references like “here we are using the result in A” but they do poorly with “I put the result in the same place every time I get a result, and I can’t randomly pick a result, I have to move all my other results out of the way!”

        I argued above that I think its no less intuitive, but most people are not terribly used to it so they don’t structure our problems in a way that lends themselves to stack-based applications.

      2. Same thing with parentheses. I don’t relish going back to trying to find where I’m lacking a missing closing parenthesis when I’m debugging. Sure, the computer tells me there’s an error in the piles of parentheses; but I don’t get any comparable when I program in Forth. I also get no type errors, and I’m also glad it has no dynamic typing.

      1. i still use my hp 21 i believe it\s rpn It used to be lots of fun to give my calculator to someone and ask them to add a few numbers ( WHERE THE HECH IS THE = SIGN?
        I just love using it still.

      1. “Forth learn you will.” ;-)

        Having read in on the basics of Forth and playing a little bit with it in the past, I realise that it is not a language for general use, but a language for very specific tasks.

        In fact I tend not to see it as a programming language per see, but more as a tiny operating system with the inner interpreter being the kernel and the outer interpreter being the interface to the kernel. I think that when properly used it will quickly become a domain specific “language” (DSL) aimed at the task at hand.

        On systems with extremely tight memory exotic techniques such as Huffman threading could be used (though some of those techniques was probably patented originally).

        From what I have read the task at hand would often be very specific, like firmware in an appliance or in a sensor. Some of the processors specifically developed to run Forth was extremely suited to real-time critical uses due to extremely low interrupt latency (4 processor cycles on late 1980’s hardware).

        As for RPN, learning it was a hassle, but using an infix (algebraic) calculator for any problems involving more than two numbers today makes me cringe. :-P

    1. There’s very little memory in each core, so to call them “Forth cores” is a bit of a misnomer. It’s not like you can take an existing Forth program, and run it on this chip. Instead, you’ll be spending a lot of time coordinating the distributed resources.

  2. In 1984, MacFORTH was the only language available for the Macintosh that didn’t require using a LI$A for development.

    I recall writing several applications on the early Mac in FORTH and even sold one to Disney and some language extensions to the MacFORTH developers.

    But really, I’d rather code in APL.

      1. I use q at work, which is based on k which owes a lot to APL. Once you get your head round left of right evaluation it’s actually a pretty nice language to code in. Very terse, you can do a lot in a single line of code. It can be a lot of fun trying to do something with as few characters as possible.

    1. “If you just want to play around with AmForth, a pre-made board like an arduino will work fine. However, if you want to integrate AmForth into your own circuits, understanding a simple, bare-bones design is useful. To that end, I’ve made a simple board based around a ATMEGA328-AU microcontroller — running at 20MHz — and a FT232R USB to serial IC.”
      -TFA

      It car be tricky to get AmForth setup on your own design, so I wanted to provide a simple worked example. (Precompiled binaries are available for arduinos.

  3. I don’t wanna be that guy, however; “at least as powerful as any 80s microcomputer or ATMega development board”.

    Looks like an ATMega development board to me. It just happens to run FORTH due to some custom firmware.

    That aside, neat project.

  4. The custom board shown just appears to be an AVR plus an FT232RL, so I can’t understand why you’d bother to design and fab a custom PCB instead of using some ordinary, cheap, off-the-shelf Arduino or Arduino-like PCB and running custom firmware on it.

    1. With a microcontroller you can do realtime hardware control, which is not possible with your desktop computer. Also its peripherals (A2D, PWM, IO ports, etc) are likely more straightforward to use than the ones in your computer that you must access through your operating system.

    2. Yes, if you want to program Forth on your computer, then this is a silly thing to do.

      That’s not how it’s meant to be used; the video just showed how it can be interactively programed.

      AmForth is meant to program microcontrollers for the things that microcontrollers usually do — controlling other, simple electronic devices. For that, it’s quite useful.

      1. Or maybe there is a compiler, but the net result is still very poor because the architecture isn’t suitable for C. Take the 6502 for instance.

        But most modern CPUs are designed to be C-friendly, so there’s no problem.

        At the same time, most CPUs are not Forth friendly.

          1. Simple. Just edit the program, compile it, and upload it to the device.

            That sure beats editing the code within the limited Forth environment with its lack of a good editor, version control, and numerous other productivity tools.

          2. Trul,

            “Simple. Just edit the program, compile it, and upload it to the device.”

            That’s exactly what it’s meant to avoid. From TFA:

            “IMHO, the killer feature of AmForth is that it runs on the microcontroller and can be used interactively; you develop directly on the device! Your big computer serves only as a serial terminal that sends text to and receives text from the microcontroller.

            Contrast this with using C: you write the code on your big computer, compile the code on your big computer, upload the code to the microcontroller, and try running the code. If it works, that’s great. If not, you have to go through the whole process again, possibly using debugging tools.

            Since AmForth can be used interactively, you just try the code, and you know right away if it works or not. Combine this with the preferred Forth coding style of breaking everything into small subroutines (that are easily tested), and you have a powerful programming tool.”

          3. Moderators: I just clicked on what I thought was “comment,” but it was “Report comment,” and I got the message “Thank you for your feedback. We will look into it.” My apologies. There’s nothing wrong with the post I clicked on, and I don’t see any way to undo my reporting.

            Now, getting on: The criticisms of Forth I see here are obviously from people with little to no experience with it. One of Forth’s advantages over C is 10:1 development speed ratio. When making a change in Forth, you don’t have to recompile the whole application, only the one new or modified definition, possibly less than ten 16-bit words. It can be instant, and the system can be running while you do it.

      1. That doesn’t make sense. You’d have to compare solving one specific problem in Forth vs C, for instance writing a Forth interpreter in Forth vs writing the same thing in C. Or compare writing a fully functional C interpreter in Forth.

      2. Unless you are trying to Sell Forth it is almost useless to try and convince people to use forth, I have found it to be like beating a Dead Horse, if you use it then it is your advantage so keep it as an advantage for your self and just connect with other Forth users. Not everyone will like the same Programming Languages. I have found over the years that many people will not even try something new with an open mind, they know the answer already and thats that!

        One advantage of Forth is you can reform it to better suite your taste. If others like the endless compile, test, edit, and recomplie and retest cycles then that is up to them, to each his own.

    1. I have competed commercially against “C” with Forth. My small team (3 people) ran rings around the 30 person “C” team. We could do in one month what they couldn’t do in six. On top of that the Military Inspector who looked at our code said it was the most readable code he had seen in a few years. The inspector came in knowing nothing about Forth.

      I LOVE using Forth when competing against “C”.

      “C” because of its stack thrash encourages a lot of bad programming practices. Not to mention having to write everything twice.

    2. C doesn’t have REPL (read eval print loop), thus a simple system with REPL is useful to provide rapid feedback engineering and facilitate troubleshooting. REPL doesn’t need to be used exclusively, it can be used in conjunction with pre-compiled code.

      In this case, REPL is FORTH interpreter.

      Another advantage is that FORTH bytecode executor and runtime can be done in 100 bytes of machine language or so, but the density of FORTH bytecode can be much higher than that of native machine instructions, if you optimize the bytecode representation and runtime towards a particular task, thus allowing to fit significantly more code into a given space at the cost of execution speed. Now consider a common case where a program has a performance hotspot and a lot of cold code. This case can be represented by mapping special opcodes to compound operations which require high performance, and implementing those in machine language or C, thus maximizing the usefulness of the system.

      Of course it’s not revolutionary but basic knowledge that every embedded engineer should have, but apparently it didn’t come to your mind, so the educational value of the project is evident.

  5. If you want to play w/ forth try mecrisp

    http://mecrisp.sourceforge.net/

    on an MSP430 or Stelaris LaunchPad.

    An important thing about forth is it was created for robotics, not general programming. Chuck Moore invented forth to solve the problems he faced automating the Kitt Peak radio telescope. He also used it to meet the original deadline for automating the Riyadh airport after the original contractor was hopelessly behind schedule. He’s also well known for reinventing forth every time he implements a project.

    http://www.forth.com/resources/evolution/evolve_2.html

  6. Forth (and LISP, which was mentioned above) fall in the “not-C” class of computer languages. People used to C don’t like them at first glance because they don’t have a C-style syntax like they’re used to. They feel the same about Haskell and ML, and audibly wonder why Perl can’t be more like C.

    The trouble with MFPLs (My Favorite Programming Languages) is that everyone considers theirs to be the most powerful. They know the features their language offers, and can see when other languages don’t offer the same features (“function pointers aren’t first-class objects? how lame”), but they don’t understand the utility offered by other languages with features their MFPL doesn’t offer.

    C-style languages go about 80% of the way up the list of support for first-class programming objects. They’re built for machines with a Harvard memory architecture, with separation between program memory and data memory, so they don’t treat ‘the code’ as a first-class programming object.

    The taste of what C-style programmers are missing lives in the short-circuit logical operators — `exp1 && exp2;`, where exp2 doesn’t even get executed if exp1 proves to be false. That’s a hardwired special cases of a more general and powerful programming technique: the ability to decide if/when code will even be interpreted. If you use C++, you also get exception handling, and a taste of type-based programming from signature-dependent function overloading.. but you have to define all your signature rules ahead of time (templates, anyone?).

    C-style languages provide a thick syntactic abstraction between “what the user writes” and “what the computer executes”. They look like the notation we were taught in math class (whose utility is arguable when you look at all the order-of-execution bugs out there (and the depth a paren nesting required to prevent them)) but keep a lot of programming power under the language’s lid in the process. It also requires specialized and notoriously complicated software to turn “what the user writes” into something a computer can execute.

    Forth and Lisp provide a thin layer of syntactic abstraction from the interpreter. “What the user writes” can be executed directly by simple code. You get to build/modify the abstract syntax tree at execution time. They provide built-in support about 90% of the way up the list of first-class programming objects, make about half the rest easily accessible, and provide fundamental support for what’s left.

  7. Apart from dabbling with Jones Forth a few years ago purely out of nostalgia, it’s 20+ years since I did any Forth. At that time I was using a Harris RTX2001 (stack based design optimised for Forth). Comparing Forth to C or any other conventional language is missing the point IMHO. It’s more like having the kernel for an OS that does what *you* want for *your* specific application, no more, no less, and no external dependency on costly (at that time) compilers, debuggers, etc, etc… just you and Forth… heaven :-) The world moved on, communication is key, which translates into code easily readable & adaptable by average programmers who longer understand computers at a hardware level.

    Nice project! Keep the flame lit!

  8. Meant to add: when coding in Forth it’s amazing how quickly you arrive at a DSL, sometimes without consciously meaning to. I suppose that’s true of many languages depending on your approach. It just seemed to be a naturally flow with Forth.

  9. I knew Chuck, he’s a great guy. I went to school with his son Eric, brother of Forth. I still have one of his custom boards running the Novix NC4000.

    One day, I went to visit Eric. His dad was developing some software. He was typing on a home-made keyboard that was made from 7 limit switches attached to his leg with Velcro. He was typing 7-bit ASCII using his fingers and left-right part of his palm. Not only was his typing very fast on that thing, he has also developed a custom predictive dictionary system that made him that much faster! Chuck was the most intelligent person I’ve ever met. I miss you Eric!

  10. /home/user/forth> more fibo
    : a . dup rot rot + dup ; : b a a a a a a a a a ; : f b b b b b b ;
    1 dup f cr bye
    /home/user/forth> cat lib1 fibo | ./forth
    1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170 1836311903 2971215073 512559680 3483774753 3996334433 3185141890 2886509027 1776683621 368225352
    /home/user/forth> wc -c forth lib1 fibo
    730 forth
    413 lib1
    82 fibo
    1225 total

    Here is a very small Forth: 730 byte, library 413 byte, fibonacci prog 82 byte.
    All together 1225 byte :-)

  11. /home/user/forth> more fibo
    : rot >r swap r> swap ;
    : a (.) 32 emit dup rot rot + dup ; : b a a a a a a a a a ; : f b b b b b ;
    1 dup f
    /home/user/forth> cat fibo | ./forth
    1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170
    /user/forth> wc -c forth fibo
    706 forth
    107 fibo
    813 total

    If we only keep the needed words, the “system” size 813 bytes :-)

  12. I am looking for a present day microcontroller that runs forth and has multitask made easy like the ISOPOD.

    One great thing about forth is that is is the only language that I know of that is a pure algebra. By this I mean is only has operators and operands. So it is ideal for genetic program. Ie. programs that write programs. PUSH POP is a good start.
    I built a “logic base” system that store all of forth code in a relational database. It took media data from the data base to generate online systems.

    The problem with Chuck Moore’s forth chip is that it did not have interrupts. If someone wants to dominate the AI field, I would think forth is the key.

    Anyway please send me any forth based micro controllers. I have a pick and place machine in my basement and can make small runs of 2-3K units.

    I enjoyed nights drink bourbon with Chuck. He lived as he though off the beaten that in the hills above silicon valley. Had a car with no motor under the hood.

    Peter
    301 916-5722

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.