Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!seismo!husc6!think!ames!ucbcad!ucbvax!dewey.soe.berkeley.edu!oster
From: oster@dewey.soe.berkeley.edu (David Phillip Oster)
Newsgroups: comp.lang.forth
Subject: Re: Forth and recursion
Message-ID: <19842@ucbvax.BERKELEY.EDU>
Date: Thu, 23-Jul-87 20:22:09 EDT
Article-I.D.: ucbvax.19842
Posted: Thu Jul 23 20:22:09 1987
Date-Received: Sat, 25-Jul-87 10:48:22 EDT
References: <1644@xanth.UUCP>
Sender: usenet@ucbvax.BERKELEY.EDU
Reply-To: oster@dewey.soe.berkeley.edu.UUCP (David Phillip Oster)
Organization: School of Education, UC-Berkeley
Lines: 59

In article <1644@xanth.UUCP> krell@xanth.UUCP (Mike Krell) writes:
>Do any implementations of Forth directly
>support recursively defined words?  Is it possible to program extensions in
>Forth that will add this capability?

Most versions of Forth already do this, if not, it is trivial to add.
The immediate problem is that since forth allows:

: PrintFour ( - ) 4 ; ( a first attempt)

: PrintFour ( - ) PrintFour . ; (oops, forgot the "print" last time)

I.e., if you use a name within the definition of that name, you
How do you get a reference to the old version. Now, how can you use a
name for recursion?

You could play games with the compiler, but that would not work for
a set of mutually recursive routines:

: g IF f THEN ;
: f IF g THEN ;

where f and g are expected to call each other. (This is the common case
for recursive forth programs, like tree walkers or complex compilers.)

What you need is the FORTH equivalent of a forward declaration.

: BADFORWARD errorPrint" unsatisfied forward reference!" ;

: FORWARD: ( - ;name declares a forward dec.)
    CREATE ['] BADFORWARD , DOES> @ EXECUTE ;

Now, for our "f" "g" example:

FORWARD: f
FORWARD: g

: (f) IF g THEN ;

' (f) SATISFIES f

: (g) IF f THEN ;

' (g) SATISFIES g

Now we just have to write SATISFIES . :

: SATISFIES ( cfa - ;name)
  ' >BODY SWAP ! ;

I hope you like this package, it is what I use myself. Obviously, one
could do better: one could have the compiler keep a chain of unsatisfied
references, and a list of words that have been forward declared. When you
define a new word, if it is on the list of forward declares, the compiler
could then patch all the references. I'd like to see the code to do this.

--- David Phillip Oster            --My Good News: "I'm a perfectionist."
Arpa: oster@dewey.soe.berkeley.edu --My Bad News: "I don't charge by the hour."
Uucp: {seismo,decvax,...}!ucbvax!oster%dewey.soe.berkeley.edu