Common Lisp:如何在父级的词法作用域中设置变量?

Hap*_*ace 3 lisp variables scope common-lisp scoping

我想定义一个函数(而不是宏),它可以在其调用的范围内设置变量。

我努力了:

(defun var-set (var-str val)
  (let ((var-interned
          (intern (string-upcase var-str))))
    (set var-interned val)
    ))

(let ((year "1400"))
  (var-set "year" 1388)
  (labeled identity year))
Run Code Online (Sandbox Code Playgroud)

由于范围规则,这不起作用。有什么“技巧”可以实现这一点吗?

在Python中,我可以使用

previous_frame = sys._getframe(1)
previous_frame_locals = previous_frame.f_locals
previous_frame_locals['my-var'] = some_value
Run Code Online (Sandbox Code Playgroud)

lisp 有等效的 API 吗?

sds*_*sds 5

您不能这样做,因为编译后该变量甚至可能不存在任何有意义的意义。例如,尝试通过查看输出来找出(disassemble (lambda (x) (+ x 4)))将在何处写入 的新值x

您必须告诉调用者和被调用者(在编译时!)该变量是special

(defun set-x (v)
  (declare (special x))
  (setq x v))
(defun test-set (a)
  (let ((x a))
    (declare (special x))
    (set-x 10)
    x))
(test-set 3)
==> 10
Run Code Online (Sandbox Code Playgroud)

有关词法绑定与动态绑定的更多详细信息,请参阅Common Lisp 中的动态和词法变量。