【问题标题】:Eliminate eval in macro using correct combination of commas and backquotes使用逗号和反引号的正确组合消除宏中的 eval
【发布时间】:2015-05-01 10:05:26
【问题描述】:

我编写了一个按预期工作的宏。问题是它包含一个eval。我想摆脱它,但尽我所能,我找不到正确的反引号和逗号组合。

(defmacro mymacro (x &body body)
  `(myothermacro ,(fun1 (eval x))
     ,@body))

这里myothermacro是一个宏,fun1是一个函数。

这是所需的行为:

(defvar v 88)

(defun fun1 (z) (1+ z))

(defmacro mymacro (x &body body)
  `(myothermacro ,(fun1 (eval x))
     ,@body))

(macroexpand-1 '(mymacro v 42 43 44)) 

    => (MYOTHERMACRO 89 42 43 44)

【问题讨论】:

  • 也许您想告诉我们您真正想要实现的目标。您的代码看起来毫无用处 - 不清楚它的用途。
  • 那是无益的评论。该代码准确地显示了我想要实现的目标。我想实现一个以与 mymacro 完全相同的方式扩展但不使用 eval 的宏。如果您不明白这一点,请说出不清楚的地方,而不是认为它没用。
  • 为什么要在宏扩展期间进行评估?你的例子没有说清楚。用例是什么?你想达到什么(不是你想做的)?这一切的目的是什么? (MYOTHERMACRO 89 42 43 44)(MYOTHERMACRO v 42 43 44) 之间几乎没有区别。您已将变量替换为宏扩展时间值。这对你的影响很小。

标签: macros common-lisp eval


【解决方案1】:

这里没有多少反引号可以为您提供帮助。在一种情况下,您有多个反引号,而准引号的数量相同,因此您可以获得不同层的引用数据,但不能多次评估数据。

了解宏在运行时不会做任何事情很重要。因此,如果您要使用一个宏,例如(mymacro variable (my-function x)),那么宏函数mymacro 会立即被输入variable(my-function x),结果就会到位。 variable 可能还不存在,因此评估它还为时过早。当您定义一个使用宏的函数时,它很可能会在存储函数之前扩展宏。在运行时没有宏,因为它们都被扩展了,但这是第一次可以得出结论,如果传递给宏的参数及其扩展根据词法环境和全局绑定实际上是有意义的。

也许如果您添加更多信息,是否有办法帮助您解决实际问题,因为我觉得这是XY problem

【讨论】:

  • 感谢您的有用回复以及您对 XY 问题的参考。我将编辑我的问题以添加一些额外的信息并希望澄清它。我的假设是在宏扩展期间可以评估x,然后评估fun1x 的值。如果这个假设是错误的,那么eval是不可避免的。
  • @user3414663 为什么需要对v 进行评估。稍后在运行时v 仍将是88?因此,一个完美的扩展将是(MYOTHERMACRO (fun1 v) 42 43 44)
  • 我将示例简化为核心。在我的应用程序中,v 是一个性别,myothermacro 依次扩展。这一切都发生在编译时。
  • 您确定宏在“运行时”不执行任何操作吗? Common Lisp 解释器呢?
  • @RainerJoswig 您在使行为实现具体化方面是正确的。一个实现有很多关于如何做事情的选择,但我认为当宏在函数被使用之前就被扩展时,对于初学者来说是最令人惊讶的。宏的副作用是一团糟。
【解决方案2】:

如果我的想法正确,您需要使用读取时评估。 像这样的:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter *foo* "foo"))

(defmacro bar (arg)
  `(list #.*foo* ,arg))

CL-USER> (macroexpand '(bar "bar"))
         (LIST "foo" "bar")

使用 defconstant 而不是 defparameter 可能会更好,因为它更清楚意图。

【讨论】:

    猜你喜欢
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    相关资源
    最近更新 更多