RECURSE

Interpretation:

Interpretation semantics for this word are undefined.

Compilation:

( -- )

Append the execution semantics of the current definition to the current definition. An ambiguous condition exists if RECURSE appears in a definition after DOES>.

See:

Rationale:

Typical use: : X ... RECURSE ... ;

This is Forth's recursion operator; in some implementations it is called MYSELF. The usual example is the coding of the factorial function.

: FACTORIAL ( +n1 -- +n2)
   DUP 2 < IF DROP 1 EXIT THEN
   DUP 1- RECURSE *
;

n2 = n1(n1-1)(n1-2)...(2)(1), the product of n1 with all positive integers less than itself (as a special case, zero factorial equals one). While beloved of computer scientists, recursion makes unusually heavy use of both stacks and should therefore be used with caution. See alternate definition in A.6.1.2140 REPEAT.

Testing:

T{ : GI6 ( N -- 0,1,..N ) 
     DUP IF DUP >R 1- RECURSE R> THEN ; -> }T

T{ 0 GI6 -> 0 }T
T{ 1 GI6 -> 0 1 }T
T{ 2 GI6 -> 0 1 2 }T
T{ 3 GI6 -> 0 1 2 3 }T
T{ 4 GI6 -> 0 1 2 3 4 }T

DECIMAL
T{ :NONAME ( n -- 0, 1, .., n ) 
     DUP IF DUP >R 1- RECURSE R> THEN 
   ; 
   CONSTANT rn1 -> }T

T{ 0 rn1 EXECUTE -> 0 }T
T{ 4 rn1 EXECUTE -> 0 1 2 3 4 }T

:NONAME ( n -- n1 )
   1- DUP
   CASE 0 OF EXIT ENDOF
     1 OF 11 SWAP RECURSE ENDOF
     2 OF 22 SWAP RECURSE ENDOF
     3 OF 33 SWAP RECURSE ENDOF
     DROP ABS RECURSE EXIT
   ENDCASE
; CONSTANT rn2

T{  1 rn2 EXECUTE -> 0 }T
T{  2 rn2 EXECUTE -> 11 0 }T
T{  4 rn2 EXECUTE -> 33 22 11 0 }T
T{ 25 rn2 EXECUTE -> 33 22 11 0 }T

ContributeContributions

enochavatar of enoch proposal: recurse' to complement recurseComment2015-12-03 23:46:08

recurse' is just like recurse but returns an XT instead of calling. It is being implemented in amforth-shadow and is mainly used by words to reschedule themselves for execution after a desired delay. A trivial example:

: every-1000ms
  ." do something" cr
  1000 0 recurse' enlist  if  ." enlist error" cr  then
;

I hope what "enlist" does can easily be guessed. If not visit my github repository :-)

Thanks, Enoch.

AntonErtlavatar of AntonErtl 2015-12-15 13:19:28

Gforth has RECURSIVE, which can be used for this purpose; e.g., your example would become:

: every-1000ms recursive \ <-- makes EVERY-1000ms visible
  ." do something" cr
  1000 0 ['] every-1000ms enlist  if  ." enlist error" cr  then
;

enochavatar of enoch 2015-12-15 15:52:07

recurse (and therefore its absent recurse' counterpart) does have a right to exist, cf. :noname and [: quotations ;] I don't like Gforth recursive declaration... it should be called "revealed" or something similar, if at all ...

ruvavatar of ruv 2015-12-30 19:14:02

IMO, recurse' is not good enough name due to use of tick (it is better to avoid special chars in names for regular words). I can suggest the name itself for such word.

enochavatar of enoch 2016-01-06 23:00:24

The use of tick ', sharp #, etc. is encouraged by the Forth Programmer’s Handbook -- Table 15: Naming conventions. We should minimize the number of names to remember thus, I would have no problem if recurse is renamed itself and completed by itself', but that's not an option for historical reasons.

Reply