在使用之前评估LISP变量是否必须?

时间:2018-01-13 19:44:30

标签: variables lisp elisp eval

我是ELISP和LISP的新手。这是一些示例代码:

(setq number 2)

(* 8 number)

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

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

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

我的问题是,我的假设是因为没有评估第一个值,第二个值不正确吗?而且,是否有更好的方法在交互模式下注册这些值,而不是逐行注册?我假设当这个应用程序正常运行时,除了在Emacs内部之外,这不是问题,只是在Emacs内部即时评估代码时的问题。

3 个答案:

答案 0 :(得分:4)

Elisp(以及像Common Lisp这样的其他Lisps)通常会评估表单。在这种情况下,您有两个表单,对应于您的两行。

(setq number 2)

(* 8 number)

组合C-j专门评估(并打印)表单。另一个有用的选项,我倾向于使用C-x C-e来评估光标前面的形式。也就是说,如果您想评估(setq number 2),则可以将光标放在)之后。

要评估整个缓冲区,您可以使用M-x eval-buffer。这将评估您在当前缓冲区中编写的所有内容。例如,您的number变量将成为"已知"之后。

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

答案 1 :(得分:4)

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

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

Emacs和其他Lisp环境通常也支持将一个或多个表单指向文件(或缓冲区)并说“评估”。这就存在一个问题,即可能不清楚究竟是什么评估以及以什么顺序。有些系统会跟踪这一点并让您说,例如,评估缓冲区中所有已更改的顶级表单'。我认为Emacs本身没有这个。

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

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

答案 2 :(得分:2)

要完成答案(是的,您必须M-x eval-buffer才能运行整个lisp代码),我们可以使用变量number进行一些操作。

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

例如,setq只是set quoted的快捷方式,因为我们希望影响符号的值。这3行当量

(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不再绑定到任何值。