我试图理解词法和动态范围的概念以及它们之间的差异。 我们来看看下面的代码:
(let ((a 1)
(b 2))
(letrec ((f (lambda () F))
(g (lambda (c) G)))
(lambda (d)
(+ (f) (g b)))))
对于表达式F和G,哪些变量位于(lambda(d)...)
的词法范围内?
答案 0 :(得分:1)
(lambda(d)...)
将d
作为绑定变量,f
,g
a
b
以及所有全局范围作为自由变量。
修改强>
只是为了演示Scheme中的代码以及其他相同绑定是动态的语言。由于您的两个函数都没有相互调用,因此您可以将它们保存在同一个let
:
(define test
(let ((a 1)
(b 2)
(f (lambda () F))
(g (lambda (c) G)))
(lambda (d)
(+ (f) (g b)))))
;; for the test we need the F and G defined
(define F 10)
(define G 20)
(test 4) ; ==> 30 (aka (+ F G))
当lambda
被评估时,即使在let
消失之后,它从词法范围使用的变量依然存在。在一个动态范围内,这不是真的:
(test 4)
; ERROR f: unbound identifier
原因是在评估lamba时存在a
,b
,f
和g
,而没有像词法范围那样捕获变量,因此当程序test
成立时,不再存在任何局部变量。事实上你不妨这样写:
;; in a dynamic lisp this s the same
(define test
(lambda (d)
(+ (f) (g b))))
当你调用函数(也就是动态的)
时,你必须确保变量存在(define g (lambda (v) 1337))
(define f (lambda () 3.1415927))
(define b 13)
(test 4) ; ==> 1340.1415927
现在,如果要在全局范围中添加上述定义并保留原始定义,则仍然会得到30
,因为词法lisp使用更接近的词法绑定而不是全局绑定。
另一个很好的例子是:
(define x 10)
(define (test v)
(+ x v))
(let ((x 20))
(test 10))
; ==> ?
在词汇lisp中,结果总是20
,因为test
对let
一无所知,因为它不在词法范围内。 x
始终是全局绑定x
。在dymamic lisp中,x
中的let
是距运行时最接近的30
,因为x
中的test
是x
与let
中x
的相同,它会影响全局XmlDocument xdoc = new XmlDocument();
// Get Request Xml for each of the case
xdoc.LoadXml(xmlContent);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xdoc.NameTable);
nsmgr.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/");
nsmgr.AddNamespace("sc", "http://tempuri.org/");
。