.. _Forward:

====================
Forward Declarations
====================

Forward declarations are used to create recursive calls if
``recurse`` cannot be used.

.. code-block:: forth

   : bar foo ;
   : foo bar ;

One solution for this task is :ref:`Defer`.

.. code-block:: forth

   Edefer foo
   : bar foo ;
   :noname ... ; is foo

This works usually. Furthermore they are based upon
standard techniques.

Another solution for forward declarations uses a Just-In-Time (JIT)
approach. With it a forward declaration resolves itself when called
without further user (or programmer) interaction:

.. code-block:: bash
   :linenos:

   > forward: foo
   > : bar foo ;
   > bar
    found only forward declaration.
   > : foo ." hey" ;
   > bar
     hey
   >

Line 1 declares foo to be defined later. This ``foo`` must not be called directly!
The next line defines a word ``bar`` that uses foo. Note that ``foo`` is not yet
a code definition. The word ``bar`` can be safely executed however. When the program 
execution of ``bar`` arrives at ``foo``, the JIT module starts. This module first gets
the name of the forwardly defined word (foo) and looks it up in the dictionary
If ``find-name`` gets an XT for ``foo`` it is checked whether it is the XT of the 
``forward:`` declaration or another one. If it is the XT of the ``forward:`` 
declaration, execution is aborted with an error message.

If an XT is found, that fulfils the requirements, two things happen: First the call 
to ``foo`` in the callee (bar) is changed from the original one (that goes to the forward
declaration) to the new one that is found by ``find-name``. Plus the XT is
executed itself. As a result, a repeated call to ``bar`` will not call the
JIT runtime checks again but hands over directly to the new foo.

``foo`` can be redefined again. Any already resolved references will remain, still not
resolved references will resolve to the new definition:

.. code-block:: forth

   > forward: foo
   > : bar foo ;
   > : baz foo ;
   > bar
     found only forward declaration.
   > : foo ." I'm number 1" ;
   > bar
     I'm number 1 ok
   > : foo ." I'm number 2" ;
   > baz
     I'm number 2 ok
   > bar
     I'm number 1 ok
   > baz
     I'm number 2 ok
   > 

The implementation uses internal data structure knowhow.
The word ``forward:`` creates words that performs the above
discussed runtime behaviour when called inside another
definition. It is assumed that they are only called within a colon
definition.

.. code-block:: forth

   : forward:
    dp create ,
    does>
    dup 1- swap @i here iplace here count ( copy to temporary ram)
    find-name if \ unless some wordlist voodoo ...
      swap over = abort" found only forward declaration."
      dup r@ 1- !i execute
    else
      \ can only happen if search wordlist has been changed
      true abort" unresolved forward declaration"
    then
   ;

Late Binding
============

A similiar definition to ``forward:`` can be used to implement late binding. In 
this case a forward reference will not get permanently resolved but looks up 
the dictionary every time it get called.

.. code-block:: forth

   : execute-late:
    dp create ,
    does>
    dup 1- swap @i here iplace here count ( copy to temporary ram)
    find-name if \ unless some wordlist voodoo...
      swap over = abort" found only forward declaration."
      execute
    else
      \ can only happen if search wordlist has changed
      true abort" unresolved forward declaration"
    then
   ;

This has a huge runtime penalty since on every invocation a dictionary lookup
will be made. An option would be the use of ``search-wordlist`` command instead of
``find-name`` if a proper (short) word list exists.

.. code-block:: bash

   > execute-late: foo
   > : bar foo ;
   > bar
     found only forward declaration.
   > : foo ." I'm number 1" ;
   > bar
     I'm number 1 ok
   > : foo ." I'm number 2" ;
   > bar
     I'm number 2 ok
   >