【问题标题】:Is it mandatory to evaluate a LISP variable before using it?在使用 LISP 变量之前是否必须对其进行评估?
【发布时间】:2018-01-13 19:44:30
【问题描述】:

总的来说,我是 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 中动态评估代码时的问题。

【问题讨论】:

    标签: variables lisp elisp eval


    【解决方案1】:

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

    (setq number 2)
    
    (* 8 number)
    

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      Emacs 和其他 Lisp 环境通常也支持指向文件(或缓冲区)中的一个或多个表单并说“评估那个”。这样做的问题是,评估的内容和顺序可能并不明显。一些系统会跟踪这一点并让您说,例如“评估缓冲区中所有更改的顶级表单”。我认为 Emacs 本身没有这个功能。

      三个交互式 Emacs 函数可能会对您有所帮助:

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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

        • 请注意,(setq x y)(set 'x y) 在比 elisp 更现代的 Lisps 中通常等效。
        猜你喜欢
        • 2012-04-15
        • 2011-12-08
        • 1970-01-01
        • 2020-02-03
        • 2017-05-26
        • 1970-01-01
        • 2012-10-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多