www.delorie.com/gnu/docs/gforth/gforth_108.html   search  
 
Buy GNU books!


Gforth Manual

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.9.9 Deferred words

The defining word Defer allows you to define a word by name without defining its behaviour; the definition of its behaviour is deferred. Here are two situation where this can be useful:

In the following example, foo always invokes the version of greet that prints "Good morning" whilst bar always invokes the version that prints "Hello". There is no way of getting foo to use the later version without re-ordering the source code and recompiling it.

 
: greet ." Good morning" ;
: foo ... greet ... ;
: greet ." Hello" ;
: bar ... greet ... ;

This problem can be solved by defining greet as a Deferred word. The behaviour of a Deferred word can be defined and redefined at any time by using IS to associate the xt of a previously-defined word with it. The previous example becomes:

 
Defer greet ( -- )
: foo ... greet ... ;
: bar ... greet ... ;
: greet1 ( -- ) ." Good morning" ;
: greet2 ( -- ) ." Hello" ;
' greet2 <IS> greet  \ make greet behave like greet2

Programming style note: You should write a stack comment for every deferred word, and put only XTs into deferred words that conform to this stack effect. Otherwise it's too difficult to use the deferred word.

A deferred word can be used to improve the statistics-gathering example from 5.9.8 User-defined Defining Words; rather than edit the application's source code to change every : to a my:, do this:

 
: real: : ;     \ retain access to the original
defer :         \ redefine as a deferred word
' my: <IS> :      \ use special version of :
\
\ load application here
\
' real: <IS> :    \ go back to the original

One thing to note is that <IS> consumes its name when it is executed. If you want to specify the name at compile time, use [IS]:

 
: set-greet ( xt -- )
  [IS] greet ;

' greet1 set-greet

A deferred word can only inherit execution semantics from the xt (because that is all that an xt can represent -- for more discussion of this see section 5.11 Tokens for Words); by default it will have default interpretation and compilation semantics deriving from this execution semantics. However, you can change the interpretation and compilation semantics of the deferred word in the usual ways:

 
: bar .... ; compile-only
Defer fred immediate
Defer jim

' bar <IS> jim  \ jim has default semantics
' bar <IS> fred \ fred is immediate

doc-defer doc-<is> doc-[is] doc-is doc-what's doc-defers

Definitions in ANS Forth for defer, <is> and [is] are provided in `compat/defer.fs'.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003