【问题标题】:Why isn't this form evaluated inside the lexical context of the let form为什么不在 let 形式的词汇上下文中评估此形式
【发布时间】:2013-04-16 14:40:33
【问题描述】:

我正在尝试创建一个宏来创建一个函数,该函数接受 S 表达式并在夹具的词法上下文中评估它们。这是我写的宏:

(defmacro def-fixture (name bindings)
  "Return a function that takes the form to execute but is wrapped between a let of the bindings"
  `(defun ,(intern (symbol-name name)) (body)
     (let (,bindings)
       (unwind-protect
           (progn
             body)))))

但是当我运行它时,它似乎在我提供的词汇上下文之外执行

(def-fixture test-fixture '(zxvf 1))

(test-fixture '(= zxvf 1))
let: Symbol's value as variable is void: zxvf

顺便说一句,我已经启用了变量词法绑定。关于我的错误有什么想法吗?

【问题讨论】:

    标签: emacs elisp lexical-scope


    【解决方案1】:

    这与词法范围无关。您的宏调用扩展为:

    (defun test-fixture (body)
      (let ((quote (zxvf 1)))
        (unwind-protect (progn body))))
    

    这当然不是你想要的。我不相信(test-fixture '(= zxvf 1)) 表示您引用的错误(即variable is void)。相反,调用信号(void-function zxvf),因为它试图评估(zxvf 1)(= zxvf 1) 表达式永远不会被计算,因为它被引用了。

    您可能想尝试更多类似的东西:

    (defmacro def-fixture (name bindings)
      "Return a macro that takes the form to execute but is wrapped between a let of the bindings"
      `(defmacro ,name (body)
         `(let (,',bindings)
            (unwind-protect
              (progn
                ,body)))))
    

    然后像这样使用它:

    (def-fixture test-fixture (zxvf 1))
    (test-fixture (= zxvf 1))
    

    【讨论】:

    • 我看到您正在使用嵌套的反引号,想知道这是否是需要的。谢谢
    【解决方案2】:

    以下注释在emacs manual

    此外,defun 或 defmacro 主体中的代码不能引用 围绕词法变量。

    这可能是你的问题。

    另外我不知道你是否需要引用def-fixture的第二个参数。我使用macrostep 包来检查生成的宏,没有引号的结果似乎更好。

    【讨论】:

    • 谢谢!我尝试返回一个 lambda,然后将宏的返回表达式绑定到一个变量。
    猜你喜欢
    • 1970-01-01
    • 2013-11-24
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多