Lisp 实现同时绑定
我正在编写一个Lisp(代码在),我想实现本地绑定。目前我有两个语法:Lisp 实现同时绑定,lisp,scheme,Lisp,Scheme,我正在编写一个Lisp(代码在),我想实现本地绑定。目前我有两个语法: (let <var> <val> <expr>) 此时此代码不运行-g关闭f,但不是相反 有没有一种规范的方法可以在Lisp中实现同时绑定?中有一节介绍了这个主题。特别是练习4.16、4.18和4.19告诉您如何实施不同的策略以实现同时定义 语法有点不同,但书中的想法归结为转换代码: (lambda <vars> (define u <e1>) (defi
(let <var> <val> <expr>)
此时此代码不运行-g
关闭f
,但不是相反
有没有一种规范的方法可以在Lisp中实现同时绑定?中有一节介绍了这个主题。特别是练习4.16、4.18和4.19告诉您如何实施不同的策略以实现同时定义
语法有点不同,但书中的想法归结为转换代码:
(lambda <vars>
(define u <e1>)
(define v <e2>)
<e3>)
(lambda <vars>
(let ((u '*unassigned*)
(v '*unassigned*))
(set! u <e1>)
(set! v <e2>)
<e3>))
(lambda
(定义u)
(定义五)
)
在此代码中:
(lambda <vars>
(define u <e1>)
(define v <e2>)
<e3>)
(lambda <vars>
(let ((u '*unassigned*)
(v '*unassigned*))
(set! u <e1>)
(set! v <e2>)
<e3>))
(lambda
(let((u'*未分配*)
(v'*未分配*)
(集!u)
(第五集)
))
同样的想法也适用于您的特殊表单。查看链接手册了解更多的实现细节。在(带(a(+2)))
中,我们将a
绑定到表达式的值(+2)
,因此a
变为4。但是在(使用((fx)(+xx))
中,我们正在做其他事情:我们正在将f
绑定到一个函数。这是(带(f(lambda(x)(+x))的)的语法糖)
要处理这种情况,必须在两个过程中处理绑定。首先收集所有变量并创建包含所有变量的环境。然后计算初始化表达式并将其值存储在相应的变量中。这些表达式的求值是在该环境中进行的,因此每个表达式对所有变量都具有可见性。初始化是通过赋值完成的。变量最初可以是
nil
,或者具有一些陷阱值,如果访问这些变量,这些陷阱值就会爆炸。您将与
一起引入变量绑定构造,但在下一个示例中,int会变形为词法函数绑定构造。这是真的吗?它是一个符号还是一个列表,在
上有区别吗?谢谢你的评论。是的,在我的实现中,让和with
绑定变量(如果
是一个符号)和词法函数(如果
是一个列表)。它们调用完全相同的底层函数-请参见我的github repo中evalappy.hs的第114-139行。祝您在Haskell中的赋值好运。:)你可以看到,这和奥斯卡的答案是一样的。您可以通过将代码转换为非相互递归的let
构造来实现这一点;我所描述的是一种直接解释它的策略,这相当于相同的事情。感谢指向SICP的指针。如果本地绑定只是代码转换,那么可能let
和with
不应该是原语,而应该是宏。你觉得怎么样?@ChrisTaylor这是个好主意。这样,语言的核心仍然很简单,其他特殊形式可以使用宏实现为语法转换。事实上,在SICPlet
、let*
、letrec
等中,都是作为语法转换实现的(在解释器级别,而不是使用宏)