(This is a snapshot of my old weblog. New posts and selected republished essays can be found at raganwald.com.)

Monday, October 15, 2007
  Until you understand how FORTH is written, you’ll have only a very superficial understanding of how to use it.

FORTH is one of those alien languages which most working programmers regard in the same way as Haskell, LISP, and so on. Something so strange that they’d rather any thoughts of it just go away so they can get on with writing this paying code. But that’s wrong and if you care at all about programming then you should at least understand all these languages, even if you will never use them.

LISP is the ultimate high-level language, and features from LISP are being added every decade to the more common languages. But FORTH is in some ways the ultimate in low level programming. Out of the box it lacks features like dynamic memory management and even strings. In fact, at its primitive level it lacks even basic concepts like IF-statements and loops.

Why then would you want to learn FORTH? There are several very good reasons. First and foremost, FORTH is minimal. You really can write a complete FORTH in, say, 2000 lines of code. I don’t just mean a FORTH program, I mean a complete FORTH operating system, environment and language. You could boot such a FORTH on a bare PC and it would come up with a prompt where you could start doing useful work. The FORTH you have here isn’t minimal and uses a Linux process as its ‘base PC’ (both for the purposes of making it a good tutorial). It’s possible to completely understand the system. Who can say they completely understand how Linux works, or gcc?

Secondly FORTH has a peculiar bootstrapping property. By that I mean that after writing a little bit of assembly to talk to the hardware and implement a few primitives, all the rest of the language and compiler is written in FORTH itself. Remember I said before that FORTH lacked IF-statements and loops? Well of course it doesn’t really because such a language would be useless, but my point was rather that IF-statements and loops are written in FORTH itself.

Now of course this is common in other languages as well, and in those languages we call them ‘libraries’. For example in C, ‘printf’ is a library function written in C. But in FORTH this goes way beyond mere libraries. Can you imagine writing C’s ‘if’ in C? And that brings me to my third reason: If you can write ‘if’ in FORTH, then why restrict yourself to the usual if/while/for/switch constructs? You want a construct that iterates over every other element in a list of numbers? You can add it to the language. What about an operator which pulls in variables directly from a configuration file and makes them available as FORTH variables? Or how about adding Makefile-like dependencies to the language? No problem in FORTH. How about modifying the FORTH compiler to allow complex inlining strategies — simple. This concept isn’t common in programming languages, but it has a name (in fact two names): “macros” (by which I mean LISP-style macros, not the lame C preprocessor) and “domain specific languages” (DSLs).

This tutorial isn’t about learning FORTH as the language. I’ll point you to some references you should read if you’re not familiar with using FORTH. This tutorial is about how to write FORTH. In fact, until you understand how FORTH is written, you’ll have only a very superficial understanding of how to use it.
—Richard M. Jones, A sometimes minimal FORTH compiler and tutorial

Comments on “Until you understand how FORTH is written, you’ll have only a very superficial understanding of how to use it.:
Read this a few weeks ago when it was posted on LtU. I am absolutely thrilled when I come across things like this. His source code/tutorial was informative, insightful, fun to read, and he really took me to a place where I wasn't expecting to go at 3am. Files like this are unexpected gems in a web full of crap.
Wow, thank you.
Also possibly of interest:

Linear Logic and Permutation Stacks – The Forth Shall Be First

(Got both of them from Kragen Sitaker.)
Excellent article, but Forth isn't "the ultimate in low level languages." It's any level you need; it has an assembler built in and, as you said, you create domain specific languages in it. What's higher level than a DSL?

<< Home
Reg Braithwaite

Recent Writing
Homoiconic Technical Writing / raganwald.posterous.com

What I‘ve Learned From Failure / Kestrels, Quirky Birds, and Hopeless Egocentricity

rewrite_rails / andand / unfold.rb / string_to_proc.rb / dsl_and_let.rb / comprehension.rb / lazy_lists.rb

IS-STRICTLY-EQUIVALENT-TO-A / Spaghetti-Western Coding / Golf is a good program spoiled / Programming conventions as signals / Not all functions should be object methods

The Not So Big Software Design / Writing programs for people to read / Why Why Functional Programming Matters Matters / But Y would I want to do a thing like this?

The single most important thing you must do to improve your programming career / The Naïve Approach to Hiring People / No Disrespect / Take control of your interview / Three tips for getting a job through a recruiter / My favourite interview question

Exception Handling in Software Development / What if powerful languages and idioms only work for small teams? / Bricks / Which theory fits the evidence? / Still failing, still learning / What I’ve learned from failure

The unary ampersand in Ruby / (1..100).inject(&:+) / The challenge of teaching yourself a programming language / The significance of the meta-circular interpreter / Block-Structured Javascript / Haskell, Ruby and Infinity / Closures and Higher-Order Functions

Why Apple is more expensive than Amazon / Why we are the biggest obstacles to our own growth / Is software the documentation of business process mistakes? / We have lost control of the apparatus / What I’ve Learned From Sales I, II, III

The Narcissism of Small Code Differences / Billy Martin’s Technique for Managing his Manager / Three stories about The Tao / Programming Language Stories / Why You Need a Degree to Work For BigCo

06/04 / 07/04 / 08/04 / 09/04 / 10/04 / 11/04 / 12/04 / 01/05 / 02/05 / 03/05 / 04/05 / 06/05 / 07/05 / 08/05 / 09/05 / 10/05 / 11/05 / 01/06 / 02/06 / 03/06 / 04/06 / 05/06 / 06/06 / 07/06 / 08/06 / 09/06 / 10/06 / 11/06 / 12/06 / 01/07 / 02/07 / 03/07 / 04/07 / 05/07 / 06/07 / 07/07 / 08/07 / 09/07 / 10/07 / 11/07 / 12/07 / 01/08 / 02/08 / 03/08 / 04/08 / 05/08 / 06/08 / 07/08 /