6.11.10.1 User-defined defining words with colon definitions

Colon definitions are very flexible, so you can write a defining word that defines a new colon definition at its run-time. Here is an example:

: myconstant {: w -- :}
  : w postpone literal postpone ; ;

When defining 5 myconstant five, myconstant first stashes w in a local (for reasons explained later), then calls :, which starts the definition of five. Then it uses postpone literal (see Compiling words) to compile w (i.e., 5) into this colon definition, and then postpone ; to end it. You can look at the result with see five:

: five  #5 ;

Can’t we just leave w on the data stack for consumption by postpone literal? No: : pushes a colon-sys on the data stack, so we have to first move w elsewhere so we can later access it. In this example, we used a local variable, but moving w on the return stack and back would also have been an option.

A more convenient, but Gforth-specific way to write myconstant is:

: myconstant {: w -- :}
  : ]] w ; [[ ;

The features used in this code are explained elsewhere (see Macros).

A disadvantage of this approach is that it consumes more memory than the approach of the next section: E.g, here are the memory costs of defining five with the various implementations:

builtin  : does> set-does> opt     
   48   64   48     48      48  bytes header+threaded code
    0   23    0      0       0  bytes native code
   16   16   32     16      16  compiled threaded code
    4   23   34      7       4  compiled native code

Builtin refers to using constant, : to using myconstant (defined above), does> to using myconstant2, set-does> to using myconstant3 (both from see User-defined defining words using create), and opt to using myconstant4 (see User-defined compile,).

The lines where the label starts with “bytes” report the space consumption of defining the word five itself; the native code is for gforth-fast on AMD64 (native code for the gforth engine is larger).

The lines where the label starts with “compiled” report the space consumption (also in bytes) for the invocation of five in the word : foo five * ;. The native code can be bigger or smaller in other contexts.