Mik*_*eC8 7 ruby lisp python scheme programming-languages
我正在Ruby中实现LISP的基本版本,以便熟悉一些概念.我的实现基于Peter Norvig的Lispy(http://norvig.com/lispy.html).
虽然这里有一些我想念的东西,但我会感激一些帮助......
他将Python的dict子类化如下:
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)
Run Code Online (Sandbox Code Playgroud)
然后,他继续解释为什么他这样做,而不仅仅是使用一个字典.然而,由于某种原因,他的解释不断透过我的眼睛,从我的脑后流出.
为什么不使用dict,然后在eval函数内部,当需要创建新的"子环境"时,只需获取现有的dict并更新需要更新的键/值对,并将新的dict传递给下一个评估?
Python解释器不会跟踪以前的"外部"环境吗?并且递归的性质不会确保将值从"内部"拉出到"外部"吗?
我正在使用Ruby,我尝试用这种方式实现.有些东西不起作用,可能是因为这个,或者可能不是.这是我的eval函数,env是常规哈希:
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
Run Code Online (Sandbox Code Playgroud)
当然,重要的是"lambda".
如果存在功能差异,那么我在这里做什么与Norvig对他的Env课程做了什么之间的重要区别?有人可以向我描述两者会偏离的情况吗?
如果没有区别,那么也许有人可以告诉我为什么Norvig使用Env类.谢谢 :)
如果Lisp中的变量绑定是不可变的,那么复制环境就等同于链接它们.但请考虑以下情况:
(define main
(lambda ()
(define i 0)
(define increment-i
(lambda ()
(set! i (+ i 1))))
(increment-i)
i))
(main)
Run Code Online (Sandbox Code Playgroud)
如果increment-i环境完全独立于main(因为它是副本),则突变i将不可见,main并且上面的代码将返回0.另一方面,如果链接环境,则返回值将1如预期的那样.
| 归档时间: |
|
| 查看次数: |
409 次 |
| 最近记录: |