Postponing ActionsThe word
POSTPONEsuppresses the immediacy of any immediate word. For example, the word
' THEN immediate? . true okSuppose we wanted to re-define
THENis immediate, we have to suppress its immediacy with
: ENDIF POSTPONE THEN ; IMMEDIATEWe have to mark
ENDIFas "immediate" because we need to replicate the immediacy of
THEN. You can then use
: xx ( n -- ) 0 > IF "positive!" ELSE "negative or zero!" ENDIF . ;While this use of
POSTPONEis trivial, more useful applications often involve adding functionality to old words.
An ExampleSuppose you wanted to count the number of words defined in your program. Instead of doing this each time by hand, one way is to amend the way the
;word works. Here's how we can do it step by step:
Step 1: Redefine ; to include a data section
: ; postpone ; ; immediate 0 ,Like
;is an immediate word, we need to
POSTPONEits action for later. Notice that there are three distinct
;in this redefinition:
- The first is the name of the new redefinition. Since it hasn't been completed, it doesn't interfere with the original definition.
- The second is fed into postpone, which compiles the XT of the old
;into the re-defined/new
- The final
;completes the redefinition. Its behaviour is the old
;. This is the last old
;is used. All subsequent uses of
;adopt the new redefinition.
Step 2: Define a new word COUNT? to retrieve the contents of ;'s data section
: ; postpone ; ; immediate 0 , : count? ['] ; @ . ;Note that
'but for compilation mode. So far, the behaviour of
Step 3: Re-Define ; again this time to increment the content of ;'s data section
: ; postpone ; ; immediate 0 , : count? ['] ; @ . ; : ; postpone ; 1 ['] ; +! ; immediateThis new redefinition contains additional behaviour -- it increments the data section entry by 1 each time it is executed. This way, we can count the number of words that have been defined.
Note that we had to define
COUNT?before this second redefinition because the latest
;doesn't have a data section. After this last definition, the word
;will count the times its is used:
: hey "Hey Jude!" . ; : double dup + ; count? 2 ok
Question 1Because we use it so often,
POSTPONEhas a short form,
`(called BACKTICK). Re-write the example above using
: ` postpone postpone ; immediate
postponeis immediate so ` should also be immediate
Question 2Could we have re-defined
;to accomplish the same purpose of counting words? Prove your answer with a program.
: : : ; 0 , : count? ['] : @ . ; : : : 1 ['] : +! ; : hey "Hey Jude!" . ; : double dup + ; count? \ 2
:is not immediate so postpone is not needed.