Related articles |
---|
Recursive environments (closures-related) pupeno@pupeno.com (Pupeno) (2007-01-17) |
Re: Recursive environments (closures-related) rsc@swtch.com (Russ Cox) (2007-01-17) |
Re: Recursive environments (closures-related) max@gustavus.edu (Max Hailperin) (2007-01-18) |
Re: Recursive environments (closures-related) gneuner2@comcast.net (George Neuner) (2007-01-18) |
Re: Recursive environments (closures-related) gneuner2@comcast.net (George Neuner) (2007-01-18) |
Re: Recursive environments (closures-related) max@gustavus.edu (Max Hailperin) (2007-01-20) |
From: | Max Hailperin <max@gustavus.edu> |
Newsgroups: | comp.compilers |
Date: | 18 Jan 2007 01:43:20 -0500 |
Organization: | Compilers Central |
References: | 07-01-050 07-01-057 |
Keywords: | Lisp |
Posted-Date: | 18 Jan 2007 01:43:20 EST |
"Russ Cox" <rsc@swtch.com> writes:
> > 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
> > environment.
>
> Whether this is correct depends on whether there can
> be objects inside the closure with their own copies
> of the environment that was used during the "interpret the value" step.
> I would imagine that there can be, and therefore that
> this is not correct.
>
> For example, if we tweak your example so you are compiling
>
> (let* ((r (lambda (x)
> (let ((x' x))
> (if (zero? x')
> x'
> (r (- x' 1))))))
> (r 10))
>
> then I would imagine that the inner let creates an environment
> containing the x' binding, and that when you patch up the
> environment for the lambda closure, you do not also patch up
> the environment for the inner let.
Actually this example would work fine. The inner let is evaluated
when the closure is applied, at which point the evaluation environment
would be the closure's patched environment.
However, here is another example where the original poster's approach
will run into trouble:
(let* ((f (let ((g (lambda (x) (f x))))
(lambda (n)
(if (= n 0)
1
(* (g (- n 1))
n))))))
(f 5))
The problem is that the closure named g needs to also be pointing to
the environment that contains f. The original poster's method won't
accomplish that. (BTW, what is called let* here is what in Scheme
would be called letrec. If you want to try the above code out in
Scheme, you need to replace let* with letrec.) -max
Return to the
comp.compilers page.
Search the
comp.compilers archives again.