代码之家  ›  专栏  ›  技术社区  ›  mikera

使宏和函数更无缝地集成

  •  6
  • mikera  · 技术社区  · 14 年前

    好的,我很清楚如何使用函数和宏。

    我很好奇的是,为什么编译器在集成这两者时不能再聪明一点,例如,考虑Clojure代码:

    (defmacro wonky-add [a b] `(+ ~a (* 2 ~b)))
    
    (defn wonky-increment [a] (apply wonky-add a 1))
    => Error: can't take value of a macro
    

    在Clojure/otherlisps中是否可以创建apply或其他更高阶函数的一个版本,这些函数和宏作为参数都能很好地工作?

    2 回复  |  直到 14 年前
        1
  •  11
  •   Rainer Joswig mmmmmm    14 年前

    这个答案不是关于Clojure,而是Lisp和宏。

    宏用于从某些源代码生成新的源代码,生成的源代码将运行。

    如果允许apply在运行时将不同的源代码输入宏,则需要能够在运行时生成结果代码并执行生成的代码。

    因此,在已编译的Lisp系统中,每次使用宏调用APPLY都可能创建需要在运行时编译才能执行的新代码。这也意味着您可能会在运行时得到新的编译器错误,当您的代码正在执行并且代码有一些问题时。因此,要在运行时应用宏,您需要一个编译器和所有必要的信息(例如其他宏),以便能够扩展和编译代码。

    这也意味着在一般情况下,不能在运行时之前使用宏编译APPLY,因为不知道要应用的运行时参数是什么。

    在早期的Lisp中,有正常的函数和所谓的fexpr。FEXPRs允许灵活的调用和运行时代码操作。在Lisp历史的后期,它们已经被宏所取代,因为宏允许高效编译,并且在基于编译器的系统中,允许在运行前处理语法错误。

        2
  •  2
  •   David X    14 年前

    你所描述的听起来像是一类宏(即:一个可以像函数一样操作的宏)。有些口齿不清有这些( Arc 例如),但是 apply ,因为它本身不是宏,所以可能仍然不起作用。