【问题标题】:eval during emacs lisp macro expansionemacs lisp 宏扩展期间的 eval
【发布时间】:2009-11-10 12:08:49
【问题描述】:

如何修复(elisp)Eval During Expansion 中的简单宏foo

以下都不起作用:

(defmacro foo1 (a)
  `(setq (eval ,a) t))

(defmacro foo2 (a)
  `(setq ,(eval a) t))

(defmacro foo3 (a)
  `(setq ,a t))

我真的不明白(elisp)Eval During Expansion 中所说的内容。我想如果我得到它,我就可以修复宏了。

更新:怀远的解决方案有效:

(defmacro foo7 (a)
  `(set ,a t))

(setq x 'b 
      a 'c)

(foo7 x)
(assert (eq b t))
(assert (eq x 'b))

(foo7 a)
(assert (eq a 'c))
(assert (eq c t))

(macroexpand '(foo7 x)) ; ==> (set x t)
(macroexpand '(foo7 a)) ; ==> (set a t)

【问题讨论】:

    标签: emacs macros elisp


    【解决方案1】:

    试试

    (defmacro foo7 (a) `(set ,a t))

    elisp 的语义对于实现来说往往是偶然的。对于一个经过深思熟虑、明确指定的宏系统的示例,我推荐Common Lisp's

    【讨论】:

      【解决方案2】:

      “修复”是什么意思?

      您所引用的页面显示,只有当您使用与宏参数不同的名称调用宏时,该宏才有效。要解决相关问题,请修改宏以减少冲突机会,或修改用法使其不发生冲突。

       (defmacro foo (aVeryLongAndImprobablyConflictingName)
         (list 'setq (eval aVeryLongAndImprobablyConflictingName) t))
      

      【讨论】:

        【解决方案3】:

        “正确”的解决方法是不需要在宏扩展函数中评估用户提供的参数。

        (defmacro foo4 (a) `(setq ,a t))

        虽然这与 foo1、foo2 或 foo3 中的任何一个都不同。您要解决的问题是什么?

        【讨论】:

        • 你的 foo4 看起来和 foo3 一样。
        • 确实如此!我什至找了那个!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-09
        • 1970-01-01
        • 2012-08-31
        • 2011-08-20
        • 1970-01-01
        • 1970-01-01
        • 2010-09-06
        相关资源
        最近更新 更多