【问题标题】:Is it possible to expand a macro into several elements?是否可以将宏扩展为多个元素?
【发布时间】:2013-09-19 05:11:02
【问题描述】:

我想要一个宏my-macro,它可以扩展为1 2 3,而不是(1 2 3),这样

(list (my-macro) 4 5) -> (1 2 3 4 5)

这可能吗?

【问题讨论】:

  • 我非常确信不是,因为要爆炸你通常使用@的列表,但这需要它在列表内才能爆炸。我找不到任何明确说明这一点的参考资料。如果你心里有一个特定的问题想用这个问题来解决,你可能想发布那个。
  • @Sim 我想将宏扩展为函数调用的参数。现在我必须使用(apply #'foo (append (my-macro) (list 4 5))) 而不是(foo (my-macro) 4 5)。后者更加简单明了。
  • @Sim 看来读宏不能做到这一点,对吧?
  • @wvxvw apply 将接受与您提供的参数一样多的参数,并且 last 必须是一个列表。所以你可以做(apply 'frob bar1 bar2 (list bar3 bar4)),它和(frob bar1 bar2 bar3 bar4)一样,但是通过同样的过程,(apply 'frob (list bar1 bar2) (list bar3 bar4))相当于(frob (list bar1 bar2) bar3 bar4)。 SaltyEgg 仍然需要附加参数列表。
  • @SaltyEgg 使用 apply,实际上更清楚,因为每个人都知道它的作用,而不是你的(实际上不可能的)宏。 lispworks.com/documentation/HyperSpec/Body/f_apply.htm#apply

标签: macros common-lisp


【解决方案1】:

不,宏不能扩展到多个值。当您需要将宏扩展为多段代码时,典型的做法是将返回值包装在 progn 中。

在您在 cmets 的示例中,看起来您使用宏不是作为语法抽象,而是作为廉价而愉快的函数优化,对此的通常反应是“请不要这样做,这是错误的并且实际上并没有做你想做的事”。

【讨论】:

    【解决方案2】:

    没有。

    在 Common Lisp 中,宏和读取宏都不能做到这一点。

    如果您真的需要,唯一的解决方案是自己编写一个完全不使用 read 的阅读器(问题是 read 将递归调用自身,而不是您的版本)。

    完全兼容的阅读器是一件相当复杂的事情,但如果您只需要功能的一个子集并且不需要使用它来阅读其他人编写的 Common Lisp 代码,那么它会很简单。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-25
      • 2012-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多