Remix.run Logo
addaon 3 days ago

> If understanding this special IMMEDIATE mode is required to understand the Forth interpreter for something as fundamental as control-flow, it seems fair to say that Forth is not a simple language. It's not just an advanced programmable RPN calculator An RPN calculator has a program counter, which makes control-flow easy to understand.

"Simple" is not a well-defined threshold but rather a continuum, so it's hard to agree or disagree with this. I think it's perfectly valid to observe that Forth is more complex than an RPN calculator, though.

But think of it this way: An RPN calculator has two types of tokens, literals and symbols. When seeing a literal, it evaluates a push of that literal to the stack. When seeing a symbol, it evaluates an immediate call to the behavior associated with that symbol.

Forth adds exactly one more concept: non-IMMEDIATE words. Everything an RPN calculator can do can be done as IMMEDIATEs in Forth. But by adding one metadata bit to the symbol table (IMMEDIATE or not), and adding a threaded call to any non-IMMEDIATE words to the output code stream, Forth gains function definition, full generic control flow support, compiler extensibility, support for embedding domain-specific languages (just IMMEDIATE words that consume the interesting tokens), and more.

I don't know if this counts as "simple" compared to C, but it surely counts as "parsimonious." It's hard to think of a more cleanly defined single semantic change that adds as much power to a language.

(And of course in C, once you understand the language understanding the runtime library is mostly about understanding runtime behavior, some macros not withstanding; but in Forth, the runtime library and the language are conflated through IMMEDIATE symbols, so this separation is much less clear; totally accept that this could be considered less "simple", although in practice most Forths have about as many pre-defined IMMEDIATE words as C has keywords.)