6.10.6 Colon Definitions

: name ( ... -- ... )
    word1 word2 word3 ;

Creates a word called name that, upon execution, executes word1 word2 word3. name is a (colon) definition.

The explanation above is somewhat superficial. For simple examples of colon definitions see Your first Forth definition. For an in-depth discussion of some of the issues involved, See Interpretation and Compilation Semantics.

: ( "name" – colon-sys  ) core “colon”
; ( compilation colon-sys – ; run-time nest-sys –  ) core “semicolon”

We plan to to perform automatic inlining eventually, but for now you can perform inlining with

inline: ( "name" – inline:-sys  ) gforth-experimental “inline-colon”

Start inline colon definition. The code between inline: and ;inline has to compile (not perform) the code to be inlined, but the resulting definition name is a colon definition that performs the inlined code. Note that the compiling code must have the stack effect ( -- ), otherwise you will get an error when Gforth tries to create the colon definition for name.

;inline ( inline:-sys –  ) gforth-experimental “semi-inline”

end inline definition started with inline:

As an example, you can define an inlined word and use it with

inline: my2dup ( a b -- a b a b )
    ]] over over [[ ;inline

#1. my2dup d. d.
: foo my2dup ;
#1. foo d. d.
see foo

Inline words are related to macros (see Macros); the difference is that a macro has immediate compilation semantics while an inline:-defined word has default compilation semantics; this means that you normally use a macro only inside a colon definition, while you can use an inline: word also interpretively. But that also means that you can do some things with macros that you cannot do as an inline: word. E.g.,

\ Doesn't work:
\   inline: endif ]] then [[ ;inline
\ Instead, write a macro:
: endif ]] then [[ ; immediate

Conversely, for words that would be fine as non-immediate colon definitions, define them as non-immediate colon definitions or (if utmost performance is required) as inline: words; don’t define them as macros, because then you cannot properly use them interpretively:

: another2dup ]] over over [[ ; immediate
\ Doesn't work:
\   #1. another2dup d. d.

You may wonder why you have to write compiling code between inline: and ;inline. That’s because the implementation of an inline word like my2dup above works similar to:

: compile-my2dup ( xt -- )
    drop ]] over over [[ ;

: my2dup [ 0 compile-my2dup ] ;
' compile-my2dup set-optimizer

The DROP and 0 are there because compile-my2dup is the implementation of compile, for my2dup, and compile, expects an xt (see User-defined compile,).