A Caveat in Using Infix Notation With FORTH

The default way in which the language FORTH works, is with Postfix Notation. Thus, if we wanted to compute the sum of 48 and 16 we would write


48 16 +


But there is a way to tease the language into using infix-notation for certain purposes. The following function will read text from the line, from which the FORTH interpreter is reading code, until a word of text has been completed, will convert this text into a number, and will push that line of text onto the stack:


: infix-number 0. bl word count >number 2drop drop ;


After this subroutine has been compiled, it can be used in the compilation of another subroutine, like so:


: infix-sum infix-number + ;


And after those two functions have been compiled, the following command will work from the top-level interpreter (of FORTH):


48 infix-sum 16


This will equally result in the sum of the two values being put on the stack, namely 64 in this example.

The problems in using this will begin, as soon as a programmer wants to use this form, in FORTH that’s supposed to be compiled. In error, a programmer could next compile a function which uses ‘infix-sum’, like so:


: output-16-higher infix-sum 16 ;


Assuming that the following line of code, given from the interpreter, will leave the value 64 on the stack again:


48 output-16-higher -?-


The reason this will fail, has to do with the fact that the FORTH-word ‘WORD‘ , expects to see a stream of text being input somewhere, when the subroutine it has been compiled into, is being executed. This needs to come from a text-stream which is being interpreted. FORTH consists of:

  1. A Text-Interpreter,
  2. A Compiler,
  3. A Bytecode-Interpreter.

When we delimit a set of words which have already been compiled, with a ‘:‘ and a ‘;‘ , we are assuming by default that each of the words used, is not to be executed, but that only its Bytecode-equivalent is to be inserted as part of the word which we are defining, which immediately follows the ‘:‘ . Thus, our example from above defines ‘output-16-higher‘ , without executing ‘infix-sum 16‘ .

Now, we might want to remedy this problem by putting


: infix-sum infix-number + ; immediate


And then indeed, as soon as the compiler encounters the word ‘infix-sum‘, it will execute that word, even during the compilation of ‘output-16-higher‘ . But then we’d run into another problem. ‘infix-sum‘ expects to receive a word off the stack. Naturally it will do so when it is executed. Does anybody know the value on the stack, while ‘output-16-higher‘ is being compiled, not executed? We want the value on the stack, when ‘output-16-higher‘ is executed.

What this dilemma also means, is that even though I now think that I’d want my own, future execution-command to be:


S" Z2VuZXJhdGUxMjM0VEVSUklCTEUuLD8K" fb64-parse 0 4 * type


To say, Use Buffer (0), I might actually want to use instead:


0 S" Z2VuZXJhdGUxMjM0VEVSUklCTEUuLD8K" fb64-parse 4 * type


To say the same thing, and To forget about using infix. Infix might be a nicety for data-input, but is the enemy, of wanting to compile our data input.