在使用 LISP 变量之前是否必须对其进行评估?

Is it mandatory to evaluate a LISP variable before using it?

总的来说,我是 ELISP 和 LISP 的新手。下面是一些示例代码:

(setq number 2)

(* 8 number)

在 lisp 交互模式下,我可以在一行的末尾使用组合键 control+j,它应该内联评估它。如果我尝试在代码 (* 2 number) 的第二行执行此操作,我会收到一条错误消息:

Debugger entered--Lisp error: (void-variable number)
  (* 8 number)

我的假设是 number 未注册为具有值。如果我在第一行代码 (setq number 2) 上执行 control+j,那么我可以在第二行使用 control+j 就好了。

我的问题是,我的假设是因为没有评估第一个值,所以第二个值不正确吗?而且,有没有比逐行注册这些值更好的方法?我假设当此应用程序正常 运行 时,除了在 Emacs 内部,这不是问题,只是在 Emacs 内部动态评估代码时的问题。

发生的事情是 Elisp(和其他 Lisp,如 Common Lisp)通常评估表单。在这种情况下,您有两种形式,对应于您的两行。

(setq number 2)

(* 8 number)

组合C-j 专门计算(并打印)一个表单。另一个可行且我倾向于使用的选项是 C-x C-e,它计算光标前的表单。也就是说,如果您想评估 (setq number 2),您可以将光标放在 ).

之后

要评估整个缓冲区,您可以使用 M-x eval-buffer。这将评估您在当前缓冲区中写入的全部内容。例如,您的 number 变量在那之后将变为 "known"。

此外,this 问题线程可能有助于阅读。

是的,你是对的。正如另一个答案所说,lisps 评估 'forms' 并且通常有两种操作模式:

  • 他们可以加载文件(或者,历史上,一些其他类型的对象),这需要顺序评估文件中的每个顶级表单;
  • 您可以与 lisp 系统对话式交互,当它评估您在其中键入的表单时。

Emacs 和其他 Lisp 环境通常也支持指向文件(或缓冲区)中的一个或多个表单并说 'evaluate that'。这有一个问题,即评估的内容和顺序可能并不明显。一些系统会跟踪这一点并让你说,例如 'evaluate all the changed top-level forms in the buffer'。我认为 Emacs 本身没有这个。

三个交互式 Emacs 功能可以帮助您:

  • eval-region 将评估该地区的表格;
  • eval-buffer 将评估整个缓冲区(就好像您选择了整个缓冲区并说 eval-region);
  • ielm(它可能不存在于所有的 emacses 中,但我认为在最近的任何东西中都存在)为您提供交互式 elisp 提示,您可以在其中键入表单以进行评估。

为了完成答案(是的,你必须 M-x eval-buffer 到 运行 你的整个 lisp 代码),我们可以玩一下你的变量 number.

在Lisp中number表示存储的,而'number表示变量"name"(或符号)。

例如,setq 只是 set quoted 的快捷方式,因为我们想要将一个值影响到一个符号。这 3 行是 equivalents:

(setq number 8)
(set 'number 8)
(set (quote number) 8)

然后你可以玩

(message (format "Result is %s" (* 8 number)))
(message (format "Result is %s" '(* 8 number)))
(message (format "Result is %s" `(* 8 ,number)))

打印:

Result is 64
Result is (* 8 number)
Result is (* 8 8)

评论:

(* 8 number) : do the computation, you get a number

'(* 8 number) : keep unevaluated form

`(* 8 ,number) : evaluate number (notice the , char) then keep in an unevaluated form

最后一件事,要将值解除绑定到符号只需使用

(makunbound 'number)

如果你现在试试

(message (format "Result is %s" (* 8 number)))

您将收到一条错误消息:

Symbol’s value as variable is void: number

确认符号 number 不再绑定到任何值。