(define make (lambda (x) (lambda (y) (cons x (list y)))))
(let ((x 7)
(p (make 4)))
(cons x (p 0)))
我是Scheme和功能程序的新手,所以我对于遍历程序有点笨拙,但是我知道如果我使用深度绑定,这个程序将返回(7 4 0)。说得通。这个程序使用浅层绑定会做什么?我觉得这听起来可能听起来很愚蠢,但这是否与重新定义有关?那么在这种情况下,我们会返回(7 0)?
基本上,我理解深度与浅层绑定的概念,但是当我看到Scheme时,我觉得自己很笨拙,因为我并不熟悉它。
请参阅此维基百科article以获取有关范围界定的讨论(它提到了词法/动态范围和深度/浅层绑定),请注意Scheme是词法范围的。 Ness的回答是否会提供更多信息。现在,让我们一步一步地看到这段代码中发生了什么:
; a variable called x is defined and assigned the value 7
(let ((x 7)
; make is called and returns a procedure p, inside its x variable has value 4
(p (make 4)))
; 7 is appended at the head of the result of calling p with y = 0
(cons x (p 0)))
=> '(7 4 0)
请注意,在第二行中,在make
返回的lambda中创建了一个闭包,并且内部的变量x
将被赋值为4
。这个x
与外部x
无关,因为Scheme是词法范围的。
最后一行不是重新定义,如前一段所述,x
中的make
与x
表达式中定义的let
不同。
深度或浅度绑定是一种实现技术,无法从程序内部观察到。程序员的区别在于词法和动态范围规则,但两者都可以用这两种技术中的任何一种来实现(即一个概念与另一个概念无关)。
深或浅是指堆栈帧的选择,以保存给定的外部范围变量的绑定。在深度绑定中,有一系列帧要访问,直到输入正确的帧来保存变量的记录;在浅层绑定中,所有绑定都存在于一个浅层环境中。另请参阅“rerooting”(仅在词法范围的浅层绑定实现的上下文中才有意义)。
根据您的具体问题,在词法范围规则下,您的代码将返回(7 4 0)
并在dynamic - (7 7 0)
下,因为调用((lambda(y) (list x y)) 0)
是在x=7
绑定的动态范围内完成的(作为旁注,(cons x (list y))
与(list x y)
相同):
x = 7
p = (lambda (y) (list x y)) ; x=4 is unused, in p=(make 4)
(cons 7 (p 0)) == (list 7 7 0) ; 'x' in this line and in lambda body for p
; both refer to same binding that is
; in effect, i.e. x=7
NB同样的术语(深度/浅层绑定)现在用于其他语言中,具有完全不同的含义(它们确实与那里的作用域规则有关),我并不完全理解。这个答案是在Scheme的背景下给出的。
参考文献:Baker的Shallow Binding in LISP 1.5,Henry G. Jr.,1977。