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: | 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.
Return to the
comp.compilers page.
Search the
comp.compilers archives again.