Macros 在运行时调用宏扩展

Macros 在运行时调用宏扩展,macros,lisp,common-lisp,Macros,Lisp,Common Lisp,是否可以在编译的lisp可执行文件中在运行时展开宏?我认为这是不可能的,因为宏扩展只能在编译前进行,但当我在编译后的代码中调用宏扩展时,我会得到输出。宏是一个函数,通常在编译或求值过程中自动调用,然后编译或求值其返回值以代替原始表达式 但是因为它只是一个函数,所以没有什么可以阻止它在运行时被显式调用,这就是MACROEXPAND和MACROEXPAND-1所做的 这大致相当于: (defun macroexpand-1 (form &optional env) (if (and (l

是否可以在编译的lisp可执行文件中在运行时展开宏?我认为这是不可能的,因为宏扩展只能在编译前进行,但当我在编译后的代码中调用宏扩展时,我会得到输出。

宏是一个函数,通常在编译或求值过程中自动调用,然后编译或求值其返回值以代替原始表达式

但是因为它只是一个函数,所以没有什么可以阻止它在运行时被显式调用,这就是
MACROEXPAND
MACROEXPAND-1
所做的

这大致相当于:

(defun macroexpand-1 (form &optional env)
  (if (and (listp form) (car form)) ;; list expression
      (let ((macfun (macro-function (car form)))
        (if macfun
            (funcall macfun form env)
            form))
      form))
(请注意,此定义不处理符号宏或使用
*MACROEXPAND-HOOK*
,以保持简单。)

定义宏时可以使用
EVAL-WHEN
使宏定义仅在编译环境中可用。如果这样做,尝试在运行时扩展将失败。

在Lisp中,术语“运行时”和“编译时”是指处理特定代码段的情况,而不是像某些静态语言中那样的绝对情况。如果我们计算
(compile nil'(lambda())
,这是
compile
函数的运行时,但是
lambda
表单的编译时:两个时间同时发生

整个语言在所有情况下都可用。构建自包含的可执行文件时,该映像不仅支持扩展宏,还支持编译代码。您的Lisp应用程序可以调用
compilefile
将Lisp源代码编译为对象形式,并调用
load
加载生成的对象代码


从Lisp应用程序映像中删除垃圾和未使用的功能以使其变小的过程称为。如果您不想在应用程序中使用编译器或宏扩展器,请了解是否/如何使用实现的树震动支持删除它们。

这与您可以在运行时调用
EVAL
的原因相同。宏在编译和求值期间会自动展开,但您仍然可以在代码中显式展开它们。