DEFER

( "<spaces>name" -- )

Skip leading space delimiters. Parse name delimited by a space. Create a definition for name with the execution semantics defined below.

name Execution:

( i * x -- j * x )

Execute the xt that name is set to execute. An ambiguous condition exists if name has not been set to execute an xt.

See:

Implementation:

: DEFER ( "name" -- )
   CREATE ['] ABORT ,
DOES> ( ... -- ... )
   @ EXECUTE ;

Testing:

T{ DEFER defer2 ->   }T
T{ ' * ' defer2 DEFER! -> }T
T{   2 3 defer2 -> 6 }T

T{ ' + IS defer2 ->   }T
T{    1 2 defer2 -> 3 }T

ContributeContributions

enochavatar of enoch DEFER this not :-)Proposal2016-09-02 16:14:36

Going Forward

Some time ago I floated on the c.l.f. mailing list the desire for future Forth specs to include some "natural" forward reference resolution mechanism rather than rely on defer (cf gforth section 5.9.10 on Deferred Words).

Unsurprisingly, I did not get an enthusiastic reception. The Forth veterans were not impressed with defer being inefficient and with defer reducing readability. So I decided to see how difficult it would be to provide such mechanism in my pet Forth project.

Since I use a Python script (amforth-shell.py) to upload Forth code to the SUT (system under test) this turned out to be a trivial task:

  1. Add an immediate Forth word (Unicode ellipsis, e.g., easy to introduce via Emacs \ldots TeX input) to display the current DP (dictionary pointer) value.

  2. The ellipsis is used to mark in compilations the beginning of the two common forward reference instances, for example: … my-last-word and … ['] my-last-word execute.

  3. Capture the above two source line instances via a simple Python regular expression: re.compile(ur"…\s+(\['\]\s+)?(\S+)", re.UNICODE). Replace group(2) with an erased Flash placeholder code (ffff in my case) and collect from the SUT into a dictionary the name to IP (instruction pointer) value mappings.

  4. A source line directive (aka a pragma), #resolve, sends to the SUT the appropriate ' name ip !i commands to patch the Flash memory appropriately.

For your consideration, Respectfully, Enoch.

P/S Why \ldots (ellipsis) for a name: It is not something that you type in by accident. It takes little space on your source line. It hints that there is more to it...

AntonErtlavatar of AntonErtl 2016-09-15 13:47:11

We discussed your request for a feature at the standards meeting. On behalf of the committee, here is our reaction:

The committee knows how to implement forward declarations without the extra fetch required by deferred words. However, the benefit (a minor speedup in a relatively rare case) does not justify the cost in our opinion.

enochavatar of enoch 2016-09-16 10:55:30

Thanks, I respect the committee's position but I beg to differ:

Readability of the source code is my main concern. Using defer to execute forward referenced target word requires introducing a new dictionary name where an undisciplined programmer may choose a name that would not be automatically associated with the target.

My proposal in a nutshell is to allow marking of forward references and let the implementer come up with his own "magic" how to go about it. Marking is not uncommon in Forth, ['] is a case in point.

Thanks, Enoch.

P/S If the committee objects to using Unicode marks, ellipsis ( ) in my implementation, so be it but I would remind everyone that we live in the 21st century and Forth inventor has long gone into color :-)

Reply