I am implementing a rudimentary version of LISP in Ruby just to familiarize myself with some concepts. I base my performance on Peter Norwig Lisp (http://norvig.com/lispy.html).
There is something missing here, and I would be happy to help ...
It subclasses the Python dict as follows:
class Env(dict): "An environment: a dict of {'var':val} pairs, with an outer Env." def __init__(self, parms=(), args=(), outer=None): self.update(zip(parms,args)) self.outer = outer def find(self, var): "Find the innermost Env where var appears." return self if var in self else self.outer.find(var)
He then goes on to explain why he is doing this, and not just using a dict. However, for some reason, his explanation continues to go through my eyes and go out through the back of my head.
Why not use a dict, and then inside the eval function, when you need to create a new "sub-environment", just take the existing dict and update the key / value pairs that need to be updated and pass that new dict to the next eval?
Will the Python interpreter keep track of previous "external" envs? And will the nature of the recursion guarantee that the values are derived from "internal" to "external"?
I use Ruby and I tried to implement things this way. Something does not work, although perhaps because of this, or maybe not. Here is my eval function, which is a regular hash:
def eval(x, env = $global_env) ........ elsif x[0] == "lambda" then ->(*args) { eval(x[2], env.merge(Hash[*x[1].zip(args).flatten(1)])) } ........ end
A line that, of course, has the meaning of "lambda."
If there is a functional difference, what is significantly different from what I'm doing here and what did Norvig do with his Env class? Can someone describe to me the case when two will deviate?
If there is no difference, then maybe someone can tell me why Norwig uses the Env class. Thanks:)