gpt4 book ai didi

emacs - 如何使用 Emacs Lisp 动态范围?

转载 作者:太空宇宙 更新时间:2023-11-03 18:31:48 25 4
gpt4 key购买 nike

我以前学过 Clojure,非常喜欢这门语言。我也喜欢 Emacs,并用 Emacs Lisp 破解了一些简单的东西。不过,有一件事让我在精神上无法用 Elisp 做任何更实质性的事情。这是动态作用域的概念。我只是害怕它,因为它对我来说太陌生了,而且闻起来像半全局变量。

所以对于变量声明,我不知道哪些事情是安全的,哪些是危险的。据我所知,用 setq 设置的变量属于动态范围(是吗?) let 变量呢?我在某处读到 let 允许您进行简单的词法范围界定,但在其他地方我读到 let vars 也是动态范围界定的。

我想我最大的担心是我的代码(使用 setq 或 let)不小心破坏了我调用的平台或第三方代码中的一些变量,或者在这样的调用之后我的局部变量被意外地弄乱了。我怎样才能避免这种情况?

是否有一些简单的经验法则,我可以遵循并确切地知道范围发生了什么,而不会被一些奇怪的、难以调试的方式所困扰?

最佳答案

还不错。

函数中的“自由变量”可能会出现主要问题。

(defun foo (a)
(* a b))

在上面的函数中,a 是一个局部变量。 b 是一个自由变量。在像 Emacs Lisp 这样具有动态绑定(bind)的系统中,b 将在运行时查找。现在有三种情况:

  1. b 未定义 -> 错误
  2. b 是一个局部变量,由当前动态范围内的某个函数调用绑定(bind) -> 取该值
  3. b 是一个全局变量 -> 取那个值

那么问题可能是:

  • 绑定(bind)值(全局或局部)被函数调用隐藏,可能是不需要的
  • 没有隐藏 undefined variable -> 访问错误
  • 全局变量未被隐藏 -> 获取全局值,这可能是不需要的

在带有编译器的 Lisp 中,编译上述函数可能会产生一个警告,指出存在一个自由变量。通常 Common Lisp 编译器会这样做。解释器不会提供该警告,只会在运行时看到效果。

建议:

  • 确保你没有意外地使用自由变量
  • 确保全局变量有一个特殊的名字,这样它们很容易在源代码中被发现,通常是*foo-var*

不要写

(defun foo (a b)
...
(setq c (* a b)) ; where c is a free variable
...)

写:

(defun foo (a b)
...
(let ((c (* a b)))
...)
...)

绑定(bind)您要使用的所有变量,并确保它们未绑定(bind)到其他地方。

基本上就是这样。

由于 GNU Emacs 版本 24,其 Emacs Lisp 支持词法绑定(bind)。请参阅:Lexical Binding, GNU Emacs Lisp Reference Manual .

关于emacs - 如何使用 Emacs Lisp 动态范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3786033/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com