宏观扩张:引用身体形式与否?

时间:2013-06-13 17:18:18

标签: emacs elisp emacs24

我很难理解宏扩展是如何运作的。 elisp解释器如何处理这两段代码有什么不同?

(defmacro foo (arg)
  (message "arg is: %s" arg))
(foo "bar")

(defmacro foo (arg)
  `(message "arg is: %s" ,arg))
(foo "bar")

1 个答案:

答案 0 :(得分:7)

你的例子可能令人困惑,因为

  1. message 显示消息,返回消息。
  2. 字符串(如“bar”)是自我评估的。
  3. 指导性示例

    (defconst zzz 123)
    (defmacro zzz1 (arg)
      `(insert (format "arg is: %s" ,arg)))
    (defmacro zzz2 (arg)
      (insert (format "arg is: %s" arg)))
    

    在3个表格中的每个表格之后使用 C-x C-e 评估上面的代码。

    现在评估这些:

    第一版:(zzz1 zzz)

    翻译......

    1. 调用zzz1
    2. 的宏功能
    3. 宏函数返回(insert (format "arg is: %s" zzz))
    4. 形式
    5. 解释器评估表单,并将"arg is: 123"插入当前缓冲区,并返回nil(在底部的回显区域中看到)
    6. 第二版:(zzz2 zzz)

      翻译......

      1. 调用zzz2
      2. 的宏功能
      3. 宏函数在当前缓冲区中插入"arg is: zzz"并返回nil
      4. 解释器评估nilnil(在回声中看到的是底部)
      5. 底线

        这里最重要的“外卖”是宏只是在解释器(编译器)启动之前对代码进行操作的函数。

        这些函数的参数未被评估(即zzz1zzz2argzzz,而非123

        它们的评估方式与任何其他lisp函数一样(例如,它们的主体中可以包含宏形式;主体包含在隐式progn;& c)中。

        他们的返回值由解释器而不是原始表单评估。