Re: Recursive environments (closures-related)

George Neuner <>
18 Jan 2007 11:30:34 -0500

          From comp.compilers

Related articles
Recursive environments (closures-related) (Pupeno) (2007-01-17)
Re: Recursive environments (closures-related) (Russ Cox) (2007-01-17)
Re: Recursive environments (closures-related) (Max Hailperin) (2007-01-18)
Re: Recursive environments (closures-related) (George Neuner) (2007-01-18)
Re: Recursive environments (closures-related) (George Neuner) (2007-01-18)
Re: Recursive environments (closures-related) (Max Hailperin) (2007-01-20)
| List of all articles for this month |

From: George Neuner <>
Newsgroups: comp.compilers
Date: 18 Jan 2007 11:30:34 -0500
Organization: Compilers Central
References: 07-01-050
Keywords: Lisp
Posted-Date: 18 Jan 2007 11:30:34 EST

Rearranged a bit for clarity
On 17 Jan 2007 17:31:39 -0500, Pupeno <> wrote:

>In PLAI, to do recursive binding it first binds r to a bogus value
>(actually a box containing a bogus value[2]) then it interprets what
>would be the real value, that is the lambda that upon interpretation
>generats a procedure. And then put that procedure where the bogus
>value was.
>I've done it differently and I'd like to know if my solution is
>wrong. I first interpret the value of the binding and bind it to its
>name creating a new environment. If the new value is a procedure then
>I change its environment for the new one (the one that contains a
>reference to itself) effectively creating the recursive

>Am I doing something wrong ? is there anything I am not seeing?

PLAI's approach is equivalent to Scheme's LETREC - it creates dummy
bindings in the current environment to act as forward references for
mutually recursive procedures.

Your solution is the equivalent of LET - only bindings in the
enclosing environment can be seen (LET* is the equivalent of nested
LETs). Allowing a recursive procedure is a nice extension.

The only issue I see with your solution (if it is important to you) is
that it doesn't directly support mutual recursion. Because you add
bindings to the environment only after evaluating the init form,
forward references to procedures not yet seen will fail. You can
still code such procedures by binding their names to dummy values and
then SET!ing them later.

Technically LETREC is all you need - Scheme also includes LET because
by creating new names up front, LETREC can unintentionally shadow
bindings in the enclosing environment, potentially resulting in use of
the wrong variable if the programmer is not careful.

>[2] Any particular reason to use a box instead of cons, car, cdr, set-car!
>and set-cdr! ?

Boxes exist for efficiency of compiled code. Logically a cons cell
works just as well for indirection.


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.