Recursive environments (closures-related)

Pupeno <pupeno@pupeno.com>
17 Jan 2007 17:31:39 -0500

          From comp.compilers

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)
| List of all articles for this month |

From: Pupeno <pupeno@pupeno.com>
Newsgroups: comp.compilers,comp.lang.lisp
Date: 17 Jan 2007 17:31:39 -0500
Organization: Compilers Central
Keywords: Lisp, question
Posted-Date: 17 Jan 2007 17:31:39 EST

Hello,
Maybe this is off-topic because I am not writting a compiler yet. I am
starting with an interpreter which is easier and I'll do that until my
language has a clear shape.


My main source of knowledge is "Programming Languages: Application and
Interpretation"[1] and I am also starting to dig in "Essentials of
Programming Languages" so, I am starting to write a Lispy language and
I am doing it in Scheme (actually I am writting a Schemy language, but
I'll get away from that soon, there's already one Scheme, or 5 or 10).
In PLAI, to do recursive binding to be able to do things such us:


(let* ((r (lambda (x)
              (if (zero? x)
                  x
                  (r (- x 1))))))
    (r 10))


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
environment. So far it seems to work and it evens has the improvement
of not requiring that the value of a recursive binding be a procedure
(since I only turn it into a recursive environment if it is a
procedure). Am I doing something wrong ? is there anything I am not
seeing ? Any thoughts are appreciated. Thank you. Pupeno
<pupeno@pupeno.com> (http://pupeno.com)


[1] http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/
[2] Any particular reason to use a box instead of cons, car, cdr, set-car!
and set-cdr! ?


PS: This is the code that interprets a recursive binding in my interpreter:


((rec-binding-node? program)
   (let* ((new-value (interpret (rec-binding-node.value program) env))
          (new-env (env.add-binding (rec-binding-node.name program)
                                    new-value
                                    env)))
    (when (closure-value? new-value)
          (set.closure-value.env! new-value new-env))
    (interpret (rec-binding-node.exp program) new-env)))


I am not sure how understandable it is without the rest of the program, but
basically the when form does the trick of setting the right environment if
and only if the value is a closure.


Post a followup to this message

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