常见的lisp中的本地动态绑定

时间:2015-06-09 00:03:11

标签: closures common-lisp dynamic-binding

谦虚地,我不确定我是否完全明白绑定是什么意思?动态"与" lexical"。但我理解当我使用defvardefparameter来定义绑定时,1。它声明了一个全局变量2.声明了绑定"特殊",所以它可以是被新的本地绑定所掩盖,例如

(defvar *x* 3)
(defun f () *x*)
(f) ;=>3
(let ((*x* 2)) (f));=>2

现在,我的问题是,是否有可能有一个具有相同属性的局部绑定(即不会污染全局环境的绑定)(即可以被"外部& #34; /"更新"绑定)?

示例:

(special-binding ((x 1)) (defun f () x))
(f);=>1
x;=>error, no binding in the global environment
(let ((x 2)) (f));=>2

我尝试在(special x)块或let中使用(locally (declare (special x)) ...)声明,但似乎没有创建闭包(从定义的函数中请求变量的值)这种方式会触发" Unbound-Variable"错误)。

2 个答案:

答案 0 :(得分:5)

您无法捕获闭包中的动态绑定,只能捕获词法绑定。

您需要在函数中声明变量special,因此它将使用动态绑定:

(let ((x 1))
  (declare (special x))
  (f))

然后你需要在调用周围动态绑定变量:

{{1}}

答案 1 :(得分:3)

首先,动态变量仅从动态绑定中获取其值,而不是词法:

(defun f ()
  (declare (special x))
  x)

(let ((x 1))
  ;; without this declaration, we would get an unbound variable error
  (declare (special x))
  (f))
;; => 1

您可以使用progv

为本地动态绑定实现默认值
(defun b ()
  (progv (if (boundp 'x) () '(x))
      (if (boundp 'x) () '(1))
    (locally (declare (special x))
      x)))

(let ((x 2))
  (declare (special x))
  (b))
;; -> 2

(b)
;; -> 1