Variables 在使用LISP变量之前,是否必须对其求值?

Variables 在使用LISP变量之前,是否必须对其求值?,variables,lisp,elisp,eval,Variables,Lisp,Elisp,Eval,一般来说,我对ELISP和LISP都是新手。下面是一些示例代码: (setq number 2) (* 8 number) 在lisp交互模式下,我可以在一行的末尾使用组合键control+j,它应该内联计算。如果我尝试在代码(*2 number)的第二行执行此操作,我会收到一条错误消息: Debugger entered--Lisp error: (void-variable number) (* 8 number) Symbol’s value as variable is voi

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

(setq number 2)

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

Debugger entered--Lisp error: (void-variable number)
  (* 8 number)
Symbol’s value as variable is void: number
我的假设是,
number
没有注册为具有值。如果我在第一行代码
(setq编号2)
上执行control+j,那么我可以在第二行代码上使用control+j


我的问题是,我的假设是因为第一个值没有计算,所以第二个值不可能是正确的吗?还有,在交互模式下,有没有比逐行注册更好的方法来注册这些值?我假设当这个应用程序正常运行时,除了在Emacs内部之外,这不是一个问题,只是在Emacs内部动态评估代码时的问题。

发生的是Elisp(以及其他Lisp,如Common Lisp)通常评估表单。在本例中,您有两个表单,对应于您的两行

(setq number 2)

(* 8 number)
组合
C-j
专门计算(并打印)表单。另一个有效的选项,我倾向于使用
C-xc-e
,它计算光标前面的表单。也就是说,如果您想计算
(setq编号2)
,您可以将光标放在
后面

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


此外,阅读问题线索可能会有所帮助。

是的,你是正确的。另一个答案是,Lisp评估“表单”,通常有两种操作模式:

  • 他们可以加载文件(或者,历史上,一些其他类型的对象),这需要依次评估文件中的每个顶级表单
  • 您可以与lisp系统进行对话式交互,此时它将评估您在其中键入的表单
Emacs和其他Lisp环境通常也支持指向文件(或缓冲区)中的一个或多个表单并说“评估它”。问题在于,评估的内容和顺序可能并不明确。一些系统会对此进行跟踪,并让您说,例如“评估缓冲区中所有更改的顶级表单”。我认为Emacs并不是天生的

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

  • eval region
    将评估该区域中的表单
  • eval buffer
    将评估整个缓冲区(就像您选择了整个缓冲区并说了
    eval region
  • ielm
    (它可能不存在于所有的emacse中,但我认为在最近的任何东西中都存在)为您提供一个交互式的elisp提示符,您可以在中键入表单进行评估
要完成答案(是的,您必须
M-x eval buffer
才能运行整个lisp代码),我们可以使用变量
number
播放一点

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

例如,
setq
只是
set quoted
的一个快捷方式,因为我们希望影响符号的值。这三条线相当于:

(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)))
您将收到一条错误消息:

Debugger entered--Lisp error: (void-variable number)
  (* 8 number)
Symbol’s value as variable is void: number
这将确认符号
编号
不再绑定到任何值

请注意,
(setq x y)
(set'x y)
在比elisp更现代的lisp中通常是不等价的。