• Recursion by name

    From Gerry Jackson@do-not-use@swldwa.uk to comp.lang.forth on Fri Jul 24 12:27:19 2026
    From Newsgroup: comp.lang.forth

    In a Forth definition recursion is achieved by the word RECURSE. It
    doesn't seem to be possible in standard Forth to achieve recursion in a
    single definition by calling the word's name. However it can be done by
    using two definitions with the same name and exploiting Forth's
    visibility rules during compilation of the recursive definition. A new recursive definition can be defined to hide the implementation details.

    The two simplest ways to implement recurse by name seem to be:

    synonym foo recurse
    and
    : foo postpone recurse ; immediate

    Each followed by the recursive definition such as:
    : foo ?dup if dup >r 1- foo r> . then ;
    10 foo \ displays 1 2 3 4 5 6 7 8 9 10

    Both solutions at first sight look a bit strange and it is better to
    hide the detail behind a new defining word such as RECURSIVE:

    Definitions of RECURSIVE: for each solution are:

    Using SYNONYM we need to build a string to evaluate e.g.

    : recursive: >in @ parse-name 2dup
    s" recurse" <# holds holds s" synonym " holds #> evaluate
    >in ! :
    ;

    EXECUTE-PARSING can be used to simplify the definition slightly.

    Using POSTPONE RECURSE

    : recursive: >in @
    : [: postpone recurse ;] compile, postpone ; immediate
    >in ! :
    ;

    The example definition of foo above gives the same result.

    recursive: foo ?dup if dup >r 1- foo r> . then ;
    10 foo

    Both definitions display 1 2 3 4 5 6 7 8 9 10
    --
    Gerry

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From albert@albert@SPENARNC.XS4ALL.NL to comp.lang.forth on Fri Jul 24 14:07:34 2026
    From Newsgroup: comp.lang.forth

    Gerry Jackson <do-not-use@swldwa.uk> wrote:
    In a Forth definition recursion is achieved by the word RECURSE. It
    doesn't seem to be possible in standard Forth to achieve recursion in a single definition by calling the word's name. However it can be done by
    using two definitions with the same name and exploiting Forth's
    visibility rules during compilation of the recursive definition. A new recursive definition can be defined to hide the implementation details.

    The two simplest ways to implement recurse by name seem to be:

    synonym foo recurse
    and
    : foo postpone recurse ; immediate

    Each followed by the recursive definition such as:
    : foo ?dup if dup >r 1- foo r> . then ;
    10 foo \ displays 1 2 3 4 5 6 7 8 9 10

    Both solutions at first sight look a bit strange and it is better to
    hide the detail behind a new defining word such as RECURSIVE:

    Definitions of RECURSIVE: for each solution are:

    Using SYNONYM we need to build a string to evaluate e.g.

    : recursive: >in @ parse-name 2dup
    s" recurse" <# holds holds s" synonym " holds #> evaluate
    >in ! :
    ;

    EXECUTE-PARSING can be used to simplify the definition slightly.

    Using POSTPONE RECURSE

    : recursive: >in @
    : [: postpone recurse ;] compile, postpone ; immediate
    >in ! :
    ;

    The example definition of foo above gives the same result.

    recursive: foo ?dup if dup >r 1- foo r> . then ;
    10 foo

    Both definitions display 1 2 3 4 5 6 7 8 9 10


    I use the following (forward, resolve)
    WANT F:
    :F GCD ;
    :R GCD OVER MOD DUP IF SWAP GCD THEN DROP ;

    Implementation is trivial, if you have not complicate your Forth.

    Both create a dea with name "GCD". Most code serve the purpose to
    make one entry invisible, and repress the "ISN;T UNQUE" message.

    It is usable for mutually recursive calls.
    :F A ;
    :F B ;
    :R A ... A ... B ... A ... ;
    :R B ... A ... B ... B ... ;

    \ Without ironcladding and whatnot:
    :R >IN @ >R NAME FOUND R> >IN !
    LATEST >DFA @ SWAP >DFA ! \ Patch the high level code in the forward dea
    ;
    :F is just an alias for : .

    Groetjes Albert
    --
    The glass is half empty. There is no such thing as a free world.
    This is the first day of the end of your life.
    If you can't beat them, ... too bad.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From albert@albert@SPENARNC.XS4ALL.NL to comp.lang.forth on Fri Jul 24 15:06:48 2026
    From Newsgroup: comp.lang.forth

    albert@spenarnc.xs4all.nl wrote:
    Gerry Jackson <do-not-use@swldwa.uk> wrote:
    In a Forth definition recursion is achieved by the word RECURSE. It
    doesn't seem to be possible in standard Forth to achieve recursion in a
    single definition by calling the word's name. However it can be done by
    using two definitions with the same name and exploiting Forth's
    visibility rules during compilation of the recursive definition. A new
    recursive definition can be defined to hide the implementation details.

    The two simplest ways to implement recurse by name seem to be:

    synonym foo recurse
    and
    : foo postpone recurse ; immediate

    Each followed by the recursive definition such as:
    : foo ?dup if dup >r 1- foo r> . then ;
    10 foo \ displays 1 2 3 4 5 6 7 8 9 10

    Both solutions at first sight look a bit strange and it is better to
    hide the detail behind a new defining word such as RECURSIVE:

    Definitions of RECURSIVE: for each solution are:

    Using SYNONYM we need to build a string to evaluate e.g.

    : recursive: >in @ parse-name 2dup
    s" recurse" <# holds holds s" synonym " holds #> evaluate
    >in ! :
    ;

    EXECUTE-PARSING can be used to simplify the definition slightly.

    Using POSTPONE RECURSE

    : recursive: >in @
    : [: postpone recurse ;] compile, postpone ; immediate
    >in ! :
    ;

    The example definition of foo above gives the same result.

    recursive: foo ?dup if dup >r 1- foo r> . then ;
    10 foo

    Both definitions display 1 2 3 4 5 6 7 8 9 10


    I use the following (forward, resolve)
    WANT F:
    :F GCD ;
    :R GCD OVER MOD DUP IF SWAP GCD THEN DROP ;

    Implementation is trivial, if you have not complicate your Forth.

    Both create a dea with name "GCD". Most code serve the purpose to
    make one entry invisible, and repress the "ISN;T UNQUE" message.

    It is usable for mutually recursive calls.
    :F A ;
    :F B ;
    :R A ... A ... B ... A ... ;
    :R B ... A ... B ... B ... ;

    \ Without ironcladding and whatnot:
    :R >IN @ >R NAME FOUND R> >IN !
    LATEST >DFA @ SWAP >DFA ! \ Patch the high level code in the forward dea
    ;
    Of course this should be
    \ Without ironcladding and whatnot:
    :R >IN @ >R NAME FOUND R> >IN ! \ Find previous definition of same name.
    : \ New definition, parse "name" again
    LATEST >DFA @ SWAP >DFA ! \ Patch the high level code in the forward dea
    ;

    :F is just an alias for : .

    Groetjes Albert
    --
    The glass is half empty. There is no such thing as a free world.
    This is the first day of the end of your life.
    If you can't beat them, ... too bad.

    --
    The glass is half empty. There is no such thing as a free world.
    This is the first day of the end of your life.
    If you can't beat them, ... too bad.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Hans Bezemer@the.beez.speaks@gmail.com to comp.lang.forth on Fri Jul 24 16:14:04 2026
    From Newsgroup: comp.lang.forth

    On 24-07-2026 13:27, Gerry Jackson wrote:

    4tH creates a symbol table entry the moment it executes ":". Hence,
    after that the compiler will find that entry and use it. So:

    : foo dup if dup >r 1- foo r> . ;then drop ;

    Indeed executes as follows:

    pp4th -x ntoc.4th
    1 2 3 4 5 6 7 8 9 10

    RECURSE required some additional thought, but it works as well. It all compiles to the very same code:

    Addr| Opcode Operand Argument

    0| branch 11 foo
    1| dup 0
    2| 0branch 9
    3| dup 0
    4| >r 0
    5| +literal -1
    6| call 0 foo
    7| r> 0
    8| . 0
    9| exit 0
    10| drop 0
    11| exit 0

    Hans Bezemer



    In a Forth definition recursion is achieved by the word RECURSE. It
    doesn't seem to be possible in standard Forth to achieve recursion in a single definition by calling the word's name. However it can be done by using two definitions with the same name and exploiting Forth's
    visibility rules during compilation of the recursive definition. A new recursive definition can be defined to hide the implementation details.

    The two simplest ways to implement recurse by name seem to be:

    synonym foo recurse
    and
    : foo-a postpone recurse ; immediate

    Each followed by the recursive definition such as:
    : foo ?dup if dup >r 1- foo r> . then-a ;
    10 foo-a \ displays 1 2 3 4 5 6 7 8 9 10

    Both solutions at first sight look a bit strange and it is better to
    hide the detail behind a new defining word such as RECURSIVE:

    Definitions of RECURSIVE: for each solution are:

    Using SYNONYM we need to build a string to evaluate e.g.

    : recursive: >in @ parse-name 2dup
    -a-a s"-a recurse" <# holds holds s" synonym " holds #> evaluate
    -a-a >in ! :
    ;

    EXECUTE-PARSING can be used to simplify the definition slightly.

    Using POSTPONE RECURSE

    : recursive:-a >in @
    -a-a-a-a : [: postpone recurse ;] compile, postpone ; immediate
    -a-a-a-a >in ! :
    ;

    The example definition of foo above gives the same result.

    recursive: foo ?dup if dup >r 1- foo r> . then-a ;
    10 foo

    Both definitions display-a-a 1 2 3 4 5 6 7 8 9 10


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Sat Jul 25 22:24:06 2026
    From Newsgroup: comp.lang.forth

    Recursion by name means changing all the references when the name changes.
    ANS notes RECURSE was originally called MYSELF - a clever name if ever
    there was. Perhaps they ought to have stayed with that.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Ron AARON@clf@8th-dev.com to comp.lang.forth on Sat Jul 25 20:58:19 2026
    From Newsgroup: comp.lang.forth

    Likewise, in 8th; which also supports 'recurse' as being useful in
    anonymous words.

    On 24/07/2026 17:14, Hans Bezemer wrote:
    On 24-07-2026 13:27, Gerry Jackson wrote:

    4tH creates a symbol table entry the moment it executes ":". Hence,
    after that the compiler will find that entry and use it. So:

    : foo dup if dup >r 1- foo r> . ;then drop ;

    Indeed executes as follows:

    pp4th -x ntoc.4th
    1 2 3 4 5 6 7 8 9 10

    RECURSE required some additional thought, but it works as well. It all compiles to the very same code:

    -a Addr| Opcode-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a Operand-a-a Argument

    -a-a-a-a 0| branch-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 11-a-a foo
    -a-a-a-a 1| dup-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 0
    -a-a-a-a 2| 0branch-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 9
    -a-a-a-a 3| dup-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 0
    -a-a-a-a 4| >r-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 0
    -a-a-a-a 5| +literal-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a -1
    -a-a-a-a 6| call-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 0-a-a foo
    -a-a-a-a 7| r>-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 0
    -a-a-a-a 8| .-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 0
    -a-a-a-a 9| exit-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 0
    -a-a-a 10| drop-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 0
    -a-a-a 11| exit-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 0

    Hans Bezemer



    In a Forth definition recursion is achieved by the word RECURSE. It
    doesn't seem to be possible in standard Forth to achieve recursion in
    a single definition by calling the word's name. However it can be done
    by using two definitions with the same name and exploiting Forth's
    visibility rules during compilation of the recursive definition. A new
    recursive definition can be defined to hide the implementation details.

    The two simplest ways to implement recurse by name seem to be:

    synonym foo recurse
    and
    : foo-a postpone recurse ; immediate

    Each followed by the recursive definition such as:
    : foo ?dup if dup >r 1- foo r> . then-a ;
    10 foo-a \ displays 1 2 3 4 5 6 7 8 9 10

    Both solutions at first sight look a bit strange and it is better to
    hide the detail behind a new defining word such as RECURSIVE:

    Definitions of RECURSIVE: for each solution are:

    Using SYNONYM we need to build a string to evaluate e.g.

    : recursive: >in @ parse-name 2dup
    -a-a-a s"-a recurse" <# holds holds s" synonym " holds #> evaluate
    -a-a-a >in ! :
    ;

    EXECUTE-PARSING can be used to simplify the definition slightly.

    Using POSTPONE RECURSE

    : recursive:-a >in @
    -a-a-a-a-a : [: postpone recurse ;] compile, postpone ; immediate
    -a-a-a-a-a >in ! :
    ;

    The example definition of foo above gives the same result.

    recursive: foo ?dup if dup >r 1- foo r> . then-a ;
    10 foo

    Both definitions display-a-a 1 2 3 4 5 6 7 8 9 10



    --- Synchronet 3.22a-Linux NewsLink 1.2