对于如下函数定义
- (let ((y 7))
-
(defun scope-test (x)
-
(list x y)))
词法作用域和动态作用域的区别在于自由变量y
对于以下运算
- (let ((y 5))
-
(scope-test 3))
动态作用域(如emacs lisp)会向前追溯运行时的y绑定,直到找到相应的y
运行结果为(3 5)
而词法作用域(如common lisp)则去检查函数定义时的环境
运行结果为(3 7)
就是说如果使用动态作用域而不小心设置了与函数定义中的自由变量相同的变量名,则会导致异常结果出现
emacs lisp使用动态作用域,这也是它的一个被诟病的地方
common lisp等由于使用词法作用域,则必须保存自由变量的相应环境,这就是闭包
对于以下函数
- (defun list+ (lst n)
-
(mapcar #’(lambda (x) (+ x n))
-
lst))
编译器必须保存响应的lambda函数才能正确执行,而这个lambda函数实际上就是一个闭包
对于如下定义
- (let ((counter 0))
-
(defun new-id () (incf counter))
-
(defun reset-id () (setq count 0)))
在common lisp中求值(new-id),得到结果为1
而在emacs lisp中直接求值(不声明任何其他的counter时),结果为出错:
- (error (void-variable counter))
即counter变量值为空,故emacs lisp不存在存储counter变量的闭包功能
阅读(2730) | 评论(0) | 转发(1) |